diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000000..067e8929ce --- /dev/null +++ b/.mailmap @@ -0,0 +1,11 @@ +Tobias Doerffel +Paul Giblock +Paul Giblock +Andrew Kelley +Andrew Kelley +Janne Sinisalo +Raine M. Ekman +Raine M. Ekman +Lukas W +Vesa +Jonathan Aquilina diff --git a/AUTHORS b/AUTHORS index 9bdf47818d..22dc31bb9b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,22 +1,30 @@ Tobias Doerffel - Maintainer, main-development, artwork etc. + Development Manager + +Jonathan Aquilina + + Project Manager Paul Giblock - development + Development Danny McRae - development + Development Javier Serrano Polo - development + Development + +Lukas Wohlschläger + + Development Andrew Kelley - development + Development Andreas Brandmaier @@ -24,12 +32,44 @@ Andreas Brandmaier Juan Fabián Simón - version 4.0 plugin artwork + Version 0.4 plugin artwork Sebastian Tilsch - recording of many samples + Recording of many samples -gabriel +Gabriel - additional artwork + Additional artwork + +Vesa Kivimäki + + UI Lead developer + +Gurjot Singh + + Developer + +Hannu Haahti + + Developer + +Uroš Maravić + + UI Developer + +Tobiasz Karoń (unfa) + + UI Developer + +Johannes Lorenz + + Developer + +Rubén Ibarra Pastor + + Developer + +LocoMatt + + 3osc skin developer diff --git a/CMakeLists.txt b/CMakeLists.txt index 397eecdeb4..b097bf538a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -303,9 +303,11 @@ IF(WANT_SYSTEM_SR) PKG_CHECK_MODULES(SAMPLERATE samplerate>=0.1.8) IF(SAMPLERATE_FOUND) SET(LMMS_HAVE_SAMPLERATE TRUE) + SET(STATUS_SAMPLERATE "OK") ENDIF(SAMPLERATE_FOUND) ENDIF(WANT_SYSTEM_SR) IF(NOT LMMS_HAVE_SAMPLERATE) + SET(STATUS_SAMPLERATE "bundled") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/3rdparty/samplerate) SET(CMAKE_CROSSCOMPILING_ORIG "${CMAKE_CROSSCOMPILING}") SET(CMAKE_CROSSCOMPILING "") @@ -355,7 +357,8 @@ IF(GIT_FOUND) COMMAND ${GIT_EXECUTABLE} shortlog -sne COMMAND cut -c8- OUTPUT_FILE ${CONTRIBUTORS} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + TIMEOUT 1) ENDIF(GIT_FOUND) SET(lmms_EMBEDDED_RESOURCES ${CMAKE_SOURCE_DIR}/AUTHORS ${CMAKE_SOURCE_DIR}/COPYING ${CONTRIBUTORS}) @@ -524,39 +527,6 @@ ADD_CUSTOM_TARGET(dist COMMAND tar cjf lmms-${VERSION}.tar.bz2 ${TMP} COMMAND rm -rf ${TMP}) -# -# add win32-pkg-target (deprecated - use "package" target instead) -# -ADD_CUSTOM_TARGET(win32-pkg - COMMAND mkdir -p tmp/lmms/data - COMMAND mkdir -p tmp/lmms/plugins/ladspa/ - COMMAND cp lmms.exe tmp/lmms - COMMAND find plugins/ -maxdepth 2 -name '*.dll' -exec cp '{}' tmp/lmms/plugins/ "';'" - COMMAND rm tmp/lmms/plugins/caps.dll - COMMAND rm tmp/lmms/plugins/tap*.dll - COMMAND cp plugins/ladspa_effect/caps/caps.dll tmp/lmms/plugins/ladspa/ - COMMAND cp plugins/ladspa_effect/tap/tap*.dll tmp/lmms/plugins/ladspa/ - COMMAND cd data && make DESTDIR=${CMAKE_BINARY_DIR}/tmp/lmms/ install - COMMAND mv tmp/lmms/opt/mingw32/share/lmms/* tmp/lmms/data/ && rm -rf tmp/lmms/opt - COMMAND cp /opt/mingw32/bin/QtCore4.dll tmp/lmms - COMMAND cp /opt/mingw32/bin/QtGui4.dll tmp/lmms - COMMAND cp /opt/mingw32/bin/QtXml4.dll tmp/lmms - COMMAND cp /opt/mingw32/bin/libz.dll tmp/lmms - COMMAND cp /opt/mingw32/bin/libsndfile-1.dll tmp/lmms - COMMAND cp /opt/mingw32/bin/libvorbis*.dll tmp/lmms - COMMAND cp /opt/mingw32/bin/libogg-0.dll tmp/lmms - COMMAND cp /opt/mingw32/bin/libfluidsynth-1.dll tmp/lmms - COMMAND cp /opt/mingw32/bin/libfftw3f-3.dll tmp/lmms - COMMAND cp /opt/mingw32/bin/SDL.dll tmp/lmms - COMMAND cp /opt/mingw32/i586-mingw32/bin/mingwm10.dll tmp/lmms - COMMAND cp -L ${CMAKE_SOURCE_DIR}/COPYING tmp/lmms/LICENSE.TXT - COMMAND cp -L ${CMAKE_SOURCE_DIR}/README tmp/lmms/README.TXT - COMMAND ${STRIP} tmp/lmms/lmms.exe tmp/lmms/plugins/*.dll tmp/lmms/plugins/ladspa/*.dll - COMMAND mv tmp/lmms tmp/lmms-${VERSION} - COMMAND cd tmp && zip -r -9 ../lmms-${VERSION}-bin-win32.zip lmms-${VERSION}/* - COMMAND rm -rf tmp -) - SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${LMMS_ER_H} ${lmms_MOC_out} ${lmms_UI_out} lmmsconfig.h lmms.1.gz") @@ -569,8 +539,7 @@ MESSAGE("\n" "Installation Summary\n" "--------------------\n" "* Install Directory : ${CMAKE_INSTALL_PREFIX}\n" -#"* Build type : ${CMAKE_BUILD_TYPE}\n" -"* Use system's libsamplerate : ${LMMS_HAVE_SAMPLERATE}\n" +"* libsamplerate : ${STATUS_SAMPLERATE}\n" ) MESSAGE( diff --git a/data/lmms.ico b/data/lmms.ico index 1b4c1d3702..507c1099ef 100644 Binary files a/data/lmms.ico and b/data/lmms.ico differ diff --git a/data/nsis_branding.bmp b/data/nsis_branding.bmp index 94691eb51d..901497e2c3 100644 Binary files a/data/nsis_branding.bmp and b/data/nsis_branding.bmp differ diff --git a/data/presets/OpulenZ/Bagpipe.xpf b/data/presets/OpulenZ/Bagpipe.xpf new file mode 100644 index 0000000000..15aae06aca --- /dev/null +++ b/data/presets/OpulenZ/Bagpipe.xpf @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Bells.xpf b/data/presets/OpulenZ/Bells.xpf new file mode 100644 index 0000000000..aade9bd6c9 --- /dev/null +++ b/data/presets/OpulenZ/Bells.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Brass.xpf b/data/presets/OpulenZ/Brass.xpf new file mode 100644 index 0000000000..f995fb96e6 --- /dev/null +++ b/data/presets/OpulenZ/Brass.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Bubbly_days.xpf b/data/presets/OpulenZ/Bubbly_days.xpf new file mode 100644 index 0000000000..bf4d925af9 --- /dev/null +++ b/data/presets/OpulenZ/Bubbly_days.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Cheesy_synth.xpf b/data/presets/OpulenZ/Cheesy_synth.xpf new file mode 100644 index 0000000000..d30fce903a --- /dev/null +++ b/data/presets/OpulenZ/Cheesy_synth.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Clarinet.xpf b/data/presets/OpulenZ/Clarinet.xpf new file mode 100644 index 0000000000..ec3357c533 --- /dev/null +++ b/data/presets/OpulenZ/Clarinet.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Combo_organ.xpf b/data/presets/OpulenZ/Combo_organ.xpf new file mode 100644 index 0000000000..92550e15c2 --- /dev/null +++ b/data/presets/OpulenZ/Combo_organ.xpf @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Epiano.xpf b/data/presets/OpulenZ/Epiano.xpf new file mode 100644 index 0000000000..cbfa3ea9a5 --- /dev/null +++ b/data/presets/OpulenZ/Epiano.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Funky.xpf b/data/presets/OpulenZ/Funky.xpf new file mode 100644 index 0000000000..e1c2baa479 --- /dev/null +++ b/data/presets/OpulenZ/Funky.xpf @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Halo_pad.xpf b/data/presets/OpulenZ/Halo_pad.xpf new file mode 100644 index 0000000000..d3769abe20 --- /dev/null +++ b/data/presets/OpulenZ/Halo_pad.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Harp.xpf b/data/presets/OpulenZ/Harp.xpf new file mode 100644 index 0000000000..e5c686d93d --- /dev/null +++ b/data/presets/OpulenZ/Harp.xpf @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Organ_leslie.xpf b/data/presets/OpulenZ/Organ_leslie.xpf new file mode 100644 index 0000000000..9f46ffed01 --- /dev/null +++ b/data/presets/OpulenZ/Organ_leslie.xpf @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Pad.xpf b/data/presets/OpulenZ/Pad.xpf new file mode 100644 index 0000000000..636ce36282 --- /dev/null +++ b/data/presets/OpulenZ/Pad.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Square.xpf b/data/presets/OpulenZ/Square.xpf new file mode 100644 index 0000000000..8c40992e4d --- /dev/null +++ b/data/presets/OpulenZ/Square.xpf @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/OpulenZ/Vibraphone.xpf b/data/presets/OpulenZ/Vibraphone.xpf new file mode 100644 index 0000000000..b41cd40e6e --- /dev/null +++ b/data/presets/OpulenZ/Vibraphone.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/projects/CoolSongs/LICENSES.TXT b/data/projects/CoolSongs/LICENSES.TXT index 94b95d9ed0..cf48776253 100644 --- a/data/projects/CoolSongs/LICENSES.TXT +++ b/data/projects/CoolSongs/LICENSES.TXT @@ -22,6 +22,10 @@ - Artistic 2.0 - http://lmms.sourceforge.net/lsp/index.php?action=show&file=581 +* MichaelKuhn-Mondscheinsonate.mmpz + - Artistic 2.0 + - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1581 + * Momo64-esp.mmpz - Artistic 2.0 - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1534 @@ -57,6 +61,10 @@ * TameAnderson-MakeMe.mmpz - Artistic 2.0 - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1060 + +* Thaledric-AwayFromBoobaloo.mmpz + - CC (by-nc-sa) + - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1187 * unfa-Spoken.mmpz - CC (by-nc) diff --git a/data/projects/Covers/MichaelKuhn-Mondscheinsonate.mmpz b/data/projects/CoolSongs/MichaelKuhn-Mondscheinsonate.mmpz similarity index 100% rename from data/projects/Covers/MichaelKuhn-Mondscheinsonate.mmpz rename to data/projects/CoolSongs/MichaelKuhn-Mondscheinsonate.mmpz diff --git a/data/projects/Covers/Thaledric-AwayFromBoobaloo.mmpz b/data/projects/CoolSongs/Thaledric-AwayFromBoobaloo.mmpz similarity index 100% rename from data/projects/Covers/Thaledric-AwayFromBoobaloo.mmpz rename to data/projects/CoolSongs/Thaledric-AwayFromBoobaloo.mmpz diff --git a/data/projects/Covers/CapDan-Infinity2010.mmpz b/data/projects/Covers/CapDan-Infinity2010.mmpz deleted file mode 100644 index 08b8705d90..0000000000 Binary files a/data/projects/Covers/CapDan-Infinity2010.mmpz and /dev/null differ diff --git a/data/projects/Covers/Edo98-FinalCountdown.mmpz b/data/projects/Covers/Edo98-FinalCountdown.mmpz deleted file mode 100644 index 61d5856e81..0000000000 Binary files a/data/projects/Covers/Edo98-FinalCountdown.mmpz and /dev/null differ diff --git a/data/projects/Covers/LICENSES.TXT b/data/projects/Covers/LICENSES.TXT deleted file mode 100644 index 066f1e8819..0000000000 --- a/data/projects/Covers/LICENSES.TXT +++ /dev/null @@ -1,20 +0,0 @@ -* CapDan-Infinity2010.mmpz - - Artistic 2.0 - - http://lmms.sourceforge.net/lsp/index.php?action=show&file=990 - -* Edo98-FinalCountdown.mmpz - - CC (by) - - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1198 - -* MichaelKuhn-Mondscheinsonate.mmpz - - Artistic 2.0 - - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1581 - -* Momo64-Jeeg.mmpz - - Artistic 2.0 - - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1380 - -* Thaledric-AwayFromBoobaloo.mmpz - - CC (by-nc-sa) - - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1187 - diff --git a/data/projects/Covers/Momo64-Jeeg.mmpz b/data/projects/Covers/Momo64-Jeeg.mmpz deleted file mode 100644 index c76c8ee326..0000000000 Binary files a/data/projects/Covers/Momo64-Jeeg.mmpz and /dev/null differ diff --git a/data/themes/default/add.png b/data/themes/default/add.png index e029787c71..f79fdfdba2 100644 Binary files a/data/themes/default/add.png and b/data/themes/default/add.png differ diff --git a/data/themes/default/apply-selected.png b/data/themes/default/apply-selected.png new file mode 100644 index 0000000000..f4e79fb4d6 Binary files /dev/null and b/data/themes/default/apply-selected.png differ diff --git a/data/themes/default/apply.png b/data/themes/default/apply.png index f547bf179a..1ae48682ea 100644 Binary files a/data/themes/default/apply.png and b/data/themes/default/apply.png differ diff --git a/data/themes/default/arp_down.png b/data/themes/default/arp_down.png index b0ce4a5cc1..85586f7dae 100644 Binary files a/data/themes/default/arp_down.png and b/data/themes/default/arp_down.png differ diff --git a/data/themes/default/arp_up.png b/data/themes/default/arp_up.png index 78e7ad37fb..07a4ecc7e4 100644 Binary files a/data/themes/default/arp_up.png and b/data/themes/default/arp_up.png differ diff --git a/data/themes/default/arp_up_and_down.png b/data/themes/default/arp_up_and_down.png index f72c0c9405..513331df7b 100644 Binary files a/data/themes/default/arp_up_and_down.png and b/data/themes/default/arp_up_and_down.png differ diff --git a/data/themes/default/automation_track.png b/data/themes/default/automation_track.png index d6193e4f6b..a7480fd70f 100644 Binary files a/data/themes/default/automation_track.png and b/data/themes/default/automation_track.png differ diff --git a/data/themes/default/autoscroll_off.png b/data/themes/default/autoscroll_off.png index c0a4f37c84..a2d56e672d 100644 Binary files a/data/themes/default/autoscroll_off.png and b/data/themes/default/autoscroll_off.png differ diff --git a/data/themes/default/autoscroll_on.png b/data/themes/default/autoscroll_on.png index 29da5c1dc6..8c4bb56900 100644 Binary files a/data/themes/default/autoscroll_on.png and b/data/themes/default/autoscroll_on.png differ diff --git a/data/themes/default/back_to_start.png b/data/themes/default/back_to_start.png index 5eb2c12bc8..d8b8b73fed 100644 Binary files a/data/themes/default/back_to_start.png and b/data/themes/default/back_to_start.png differ diff --git a/data/themes/default/back_to_zero.png b/data/themes/default/back_to_zero.png index b89c2107a3..dfde88b4e5 100644 Binary files a/data/themes/default/back_to_zero.png and b/data/themes/default/back_to_zero.png differ diff --git a/data/themes/default/bb_track.png b/data/themes/default/bb_track.png index 155664925d..a260177415 100644 Binary files a/data/themes/default/bb_track.png and b/data/themes/default/bb_track.png differ diff --git a/data/themes/default/bb_track_btn.png b/data/themes/default/bb_track_btn.png new file mode 100644 index 0000000000..515e9711c5 Binary files /dev/null and b/data/themes/default/bb_track_btn.png differ diff --git a/data/themes/default/chord.png b/data/themes/default/chord.png index 8aa83cdbeb..42165f6b0a 100644 Binary files a/data/themes/default/chord.png and b/data/themes/default/chord.png differ diff --git a/data/themes/default/combobox_bg.png b/data/themes/default/combobox_bg.png index 92430c2521..83bdb41406 100644 Binary files a/data/themes/default/combobox_bg.png and b/data/themes/default/combobox_bg.png differ diff --git a/data/themes/default/cpuload_bg.png b/data/themes/default/cpuload_bg.png index e0f4a1581c..f05db1a069 100644 Binary files a/data/themes/default/cpuload_bg.png and b/data/themes/default/cpuload_bg.png differ diff --git a/data/themes/default/cpuload_leds.png b/data/themes/default/cpuload_leds.png index cbb3bd478c..900cd5b460 100644 Binary files a/data/themes/default/cpuload_leds.png and b/data/themes/default/cpuload_leds.png differ diff --git a/data/themes/default/dont_know.png b/data/themes/default/dont_know.png index 21a0cab627..3924a91734 100644 Binary files a/data/themes/default/dont_know.png and b/data/themes/default/dont_know.png differ diff --git a/data/themes/default/edit_select.png b/data/themes/default/edit_select.png index 5019cd89a0..11b674a605 100644 Binary files a/data/themes/default/edit_select.png and b/data/themes/default/edit_select.png differ diff --git a/data/themes/default/exp_wave_active.png b/data/themes/default/exp_wave_active.png index 48b4b5a897..22682a150a 100644 Binary files a/data/themes/default/exp_wave_active.png and b/data/themes/default/exp_wave_active.png differ diff --git a/data/themes/default/home.png b/data/themes/default/home.png index 647e753380..84051dbb6e 100644 Binary files a/data/themes/default/home.png and b/data/themes/default/home.png differ diff --git a/data/themes/default/icon.png b/data/themes/default/icon.png index 2753bc3528..0247da5929 100644 Binary files a/data/themes/default/icon.png and b/data/themes/default/icon.png differ diff --git a/data/themes/default/keep_stop_position.png b/data/themes/default/keep_stop_position.png index 060297da2c..561fead250 100644 Binary files a/data/themes/default/keep_stop_position.png and b/data/themes/default/keep_stop_position.png differ diff --git a/data/themes/default/lfo_d100_active.png b/data/themes/default/lfo_d100_active.png index f2a05b5554..bb966c5799 100644 Binary files a/data/themes/default/lfo_d100_active.png and b/data/themes/default/lfo_d100_active.png differ diff --git a/data/themes/default/lfo_x100_active.png b/data/themes/default/lfo_x100_active.png index 479ff38c12..cb563f432e 100644 Binary files a/data/themes/default/lfo_x100_active.png and b/data/themes/default/lfo_x100_active.png differ diff --git a/data/themes/default/lfo_x1_active.png b/data/themes/default/lfo_x1_active.png index 3a44b3e288..2c54a6ab1d 100644 Binary files a/data/themes/default/lfo_x1_active.png and b/data/themes/default/lfo_x1_active.png differ diff --git a/data/themes/default/moog_saw_wave_active.png b/data/themes/default/moog_saw_wave_active.png index 9a530a1b3e..f6230f6d40 100644 Binary files a/data/themes/default/moog_saw_wave_active.png and b/data/themes/default/moog_saw_wave_active.png differ diff --git a/data/themes/default/note.png b/data/themes/default/note.png index f81425daed..9e80341e09 100644 Binary files a/data/themes/default/note.png and b/data/themes/default/note.png differ diff --git a/data/themes/default/note_double_whole.png b/data/themes/default/note_double_whole.png index 4b1e934bd6..f55150f462 100644 Binary files a/data/themes/default/note_double_whole.png and b/data/themes/default/note_double_whole.png differ diff --git a/data/themes/default/note_eighth.png b/data/themes/default/note_eighth.png index f81425daed..f7cac86895 100644 Binary files a/data/themes/default/note_eighth.png and b/data/themes/default/note_eighth.png differ diff --git a/data/themes/default/note_half.png b/data/themes/default/note_half.png index aff73e5931..1444bcf113 100644 Binary files a/data/themes/default/note_half.png and b/data/themes/default/note_half.png differ diff --git a/data/themes/default/note_quarter.png b/data/themes/default/note_quarter.png index 6c3acf2cd6..acd47baabc 100644 Binary files a/data/themes/default/note_quarter.png and b/data/themes/default/note_quarter.png differ diff --git a/data/themes/default/note_sixteenth.png b/data/themes/default/note_sixteenth.png index 661bcb7be0..44c900cebd 100644 Binary files a/data/themes/default/note_sixteenth.png and b/data/themes/default/note_sixteenth.png differ diff --git a/data/themes/default/note_thirtysecond.png b/data/themes/default/note_thirtysecond.png index a3daee5792..204325edc5 100644 Binary files a/data/themes/default/note_thirtysecond.png and b/data/themes/default/note_thirtysecond.png differ diff --git a/data/themes/default/note_tripleteighth.png b/data/themes/default/note_tripleteighth.png index 4e4d214dea..3cd7ea452b 100644 Binary files a/data/themes/default/note_tripleteighth.png and b/data/themes/default/note_tripleteighth.png differ diff --git a/data/themes/default/note_triplethalf.png b/data/themes/default/note_triplethalf.png index 5c8a7e90c8..a2c80fe194 100644 Binary files a/data/themes/default/note_triplethalf.png and b/data/themes/default/note_triplethalf.png differ diff --git a/data/themes/default/note_tripletquarter.png b/data/themes/default/note_tripletquarter.png index 39c037b2a2..029a503006 100644 Binary files a/data/themes/default/note_tripletquarter.png and b/data/themes/default/note_tripletquarter.png differ diff --git a/data/themes/default/note_tripletsixteenth.png b/data/themes/default/note_tripletsixteenth.png index a307b542a9..31ce419423 100644 Binary files a/data/themes/default/note_tripletsixteenth.png and b/data/themes/default/note_tripletsixteenth.png differ diff --git a/data/themes/default/note_tripletthirtysecond.png b/data/themes/default/note_tripletthirtysecond.png index 20e2ab65aa..9f8b31122b 100644 Binary files a/data/themes/default/note_tripletthirtysecond.png and b/data/themes/default/note_tripletthirtysecond.png differ diff --git a/data/themes/default/note_whole.png b/data/themes/default/note_whole.png index f178b50237..36c2308b9e 100644 Binary files a/data/themes/default/note_whole.png and b/data/themes/default/note_whole.png differ diff --git a/data/themes/default/output_graph.png b/data/themes/default/output_graph.png index b1405a63b5..46ec86d447 100644 Binary files a/data/themes/default/output_graph.png and b/data/themes/default/output_graph.png differ diff --git a/data/themes/default/pause.png b/data/themes/default/pause.png index c9b45d7d94..04725f997e 100644 Binary files a/data/themes/default/pause.png and b/data/themes/default/pause.png differ diff --git a/data/themes/default/play.png b/data/themes/default/play.png index eea2cf9b64..ee66b4929e 100644 Binary files a/data/themes/default/play.png and b/data/themes/default/play.png differ diff --git a/data/themes/default/plugins.png b/data/themes/default/plugins.png index b7cff0117d..5ba9bc3c90 100644 Binary files a/data/themes/default/plugins.png and b/data/themes/default/plugins.png differ diff --git a/data/themes/default/preset_file.png b/data/themes/default/preset_file.png index c9897ae406..53a0d1159e 100644 Binary files a/data/themes/default/preset_file.png and b/data/themes/default/preset_file.png differ diff --git a/data/themes/default/project_file.png b/data/themes/default/project_file.png index db0fe6e1fd..724ab5cfb2 100644 Binary files a/data/themes/default/project_file.png and b/data/themes/default/project_file.png differ diff --git a/data/themes/default/record.png b/data/themes/default/record.png index 1251079589..fc1d435d35 100644 Binary files a/data/themes/default/record.png and b/data/themes/default/record.png differ diff --git a/data/themes/default/record_accompany.png b/data/themes/default/record_accompany.png index 0dbbb91b94..7dd091a124 100644 Binary files a/data/themes/default/record_accompany.png and b/data/themes/default/record_accompany.png differ diff --git a/data/themes/default/reload.png b/data/themes/default/reload.png index 699153a938..c92882ecdc 100644 Binary files a/data/themes/default/reload.png and b/data/themes/default/reload.png differ diff --git a/data/themes/default/round_square_wave_active.png b/data/themes/default/round_square_wave_active.png index b2d794d393..0dfe2093ad 100644 Binary files a/data/themes/default/round_square_wave_active.png and b/data/themes/default/round_square_wave_active.png differ diff --git a/data/themes/default/sample_file.png b/data/themes/default/sample_file.png index 30814a1b92..f2ed8d46e0 100644 Binary files a/data/themes/default/sample_file.png and b/data/themes/default/sample_file.png differ diff --git a/data/themes/default/sample_track.png b/data/themes/default/sample_track.png index 754146f3ef..4df4ca8e1b 100644 Binary files a/data/themes/default/sample_track.png and b/data/themes/default/sample_track.png differ diff --git a/data/themes/default/saw_wave_active.png b/data/themes/default/saw_wave_active.png index 648910b6b1..62bffcc336 100644 Binary files a/data/themes/default/saw_wave_active.png and b/data/themes/default/saw_wave_active.png differ diff --git a/data/themes/default/scale.png b/data/themes/default/scale.png index fa680ab767..4b6e1427f9 100644 Binary files a/data/themes/default/scale.png and b/data/themes/default/scale.png differ diff --git a/data/themes/default/sin_wave_active.png b/data/themes/default/sin_wave_active.png index 57e06d4089..ec7bf0a7d0 100644 Binary files a/data/themes/default/sin_wave_active.png and b/data/themes/default/sin_wave_active.png differ diff --git a/data/themes/default/square_wave_active.png b/data/themes/default/square_wave_active.png index a79a22b98b..487b5aff74 100644 Binary files a/data/themes/default/square_wave_active.png and b/data/themes/default/square_wave_active.png differ diff --git a/data/themes/default/stop.png b/data/themes/default/stop.png index 4e64f396c4..2d204586ab 100644 Binary files a/data/themes/default/stop.png and b/data/themes/default/stop.png differ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 5dde749772..94a4b393ca 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -1,4 +1,6 @@ -/* LMMS style sheet */ +/******************** + * LMMS style sheet * + ********************/ QWhatsThat { color: black; @@ -12,6 +14,7 @@ AutomationEditor { background-color: rgb(0, 0, 0); } +/* text box */ QLineEdit { border-radius: 4px; @@ -20,6 +23,8 @@ QLineEdit { color: #e0e0e0; } +/* text box when it wants text */ + QLineEdit:focus { border: 1px solid rgba(0,0,0, 128); } @@ -89,6 +94,20 @@ pianoRoll { background-color: rgb(0, 0, 0); } +/* main toolbar oscilloscope - can have transparent bg now */ + +visualizationWidget { + background: none; + border: none; +} + +/* main toolbar cpu load widget - this can have transparent bg now */ + +cpuloadWidget { + border: none; + background: url(resources:cpuload_bg.png); +} + /* scrollbar: trough */ QScrollBar:horizontal { @@ -121,7 +140,7 @@ QScrollBar::add-page:vertical:pressed, QScrollBar::sub-page:vertical:pressed { QScrollBar::handle:horizontal { background: qlineargradient(spread:reflect, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 #747474, stop:0.5 #c9c9c9, stop:1 #808080); + stop:0 #969696, stop:0.5 #c9c9c9, stop:1 #aaa); border: 1px outset #888; border-radius: 2px; min-width: 24px; @@ -130,7 +149,7 @@ QScrollBar::handle:horizontal { QScrollBar::handle:horizontal:hover { background: qlineargradient(spread:reflect, x1:0.5, y1:0, x2:0.5, y2:1, - stop:0 #747474, stop:0.5 #f0f0f0, stop:1 #808080); + stop:0 #969696, stop:0.5 #f0f0f0, stop:1 #aaa); } QScrollBar::handle:horizontal:pressed { @@ -142,7 +161,7 @@ QScrollBar::handle:horizontal:pressed { QScrollBar::handle:vertical { background: qlineargradient(spread:reflect, x1:0, y1:0.5, x2:1, y2:0.5, - stop:0 #747474, stop:0.5 #c9c9c9, stop:1 #808080); + stop:0 #969696, stop:0.5 #c9c9c9, stop:1 #aaa); border: 1px outset #888; border-radius: 2px; min-height: 24px; @@ -151,7 +170,7 @@ QScrollBar::handle:vertical { QScrollBar::handle:vertical:hover { background: qlineargradient(spread:reflect, x1:0, y1:0.5, x2:1, y2:0.5, - stop:0 #747474, stop:0.5 #f0f0f0, stop:1 #808080); + stop:0 #969696, stop:0.5 #f0f0f0, stop:1 #aaa); } QScrollBar::handle:vertical:pressed { @@ -192,6 +211,8 @@ QScrollBar::add-line:disabled, QScrollBar::sub-line:disabled { background: #747474; } +/* arrow button arrows */ + QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal, QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { border: none; @@ -209,18 +230,23 @@ QScrollBar::right-arrow:horizontal:disabled { background-image: url(resources:sb QScrollBar::up-arrow:vertical:disabled { background-image: url(resources:sbarrow_up_d.png);} QScrollBar::down-arrow:vertical:disabled { background-image: url(resources:sbarrow_down_d.png);} +/* background for song editor and bb-editor */ TrackContainerView QFrame{ background-color: #49515b; } -nStateButton { +/* autoscroll, loop, stop behaviour toggle buttons */ + +nStateButton { max-height: 26px; max-width: 26px; min-height: 26px; min-width: 26px; } +/* gear button in tracks */ + trackOperationsWidget > QPushButton { max-height: 26px; max-width: 26px; @@ -251,15 +277,19 @@ trackOperationsWidget > QPushButton::menu-indicator:checked top: 3px; } -trackWidget { -/* border-bottom: 1px solid rgb(0, 0, 0);*/ +/* actually has no effect yet so disabled */ +/*trackWidget { +/* border-bottom: 1px solid rgb(0, 0, 0);*//* background-color: rgb(0, 0, 0); -} +}*/ + +/* font sizes */ + nameLabel, effectLabel, sf2InstrumentView > QLabel { font-size:10px; } - +/* main toolbar sliders (master vol, master pitch) */ automatableSlider::groove:vertical { background: rgba(0,0,0, 128); @@ -278,11 +308,14 @@ automatableSlider::handle:vertical { margin: -4px -12px -2px; } +/* window that shows up when you add effects */ EffectSelectDialog QScrollArea { background: #5b6571; } +/* the inner boxes in LADSPA effect windows */ + EffectControlDialog QGroupBox { background: #49515b; margin-top: 1ex; @@ -291,6 +324,8 @@ EffectControlDialog QGroupBox { border: 1px solid rgba(0,0,0, 64); } +/* the inner box titles when present (channel 1, channel 2...) */ + EffectControlDialog QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; @@ -301,10 +336,14 @@ EffectControlDialog QGroupBox::title { padding: 2px 1px; } +/* main toolbar */ + QWidget#mainToolbar { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #98a2a7, stop:1 #5b646f); } +/* smaller toolbars */ + QToolBar { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #98a2a7, stop:1 #5b646f); } @@ -318,6 +357,22 @@ QToolButton, toolButton { color: black; } +/* separate corner rounding for play and stop buttons! */ + +toolButton#playButton { + border-top-left-radius: 8px 6px; + border-bottom-left-radius: 8px 6px; +} + +toolButton#stopButton { + border-top-right-radius: 8px 6px; + border-bottom-right-radius: 8px 6px; +} + +/* record and record-accompany can be styled with #recordButton and #recordAccompanyButton respectively */ + +/* all tool buttons */ + QToolButton:hover, toolButton:hover { background: qradialgradient(cx:0.3, cy:0.3, radius:0.8, fx:0.3, fy:0.3, stop:0 #e0e0e0, stop:0.5 #c9c9c9, stop:1 #969696 ); border: 1px solid rgba(0,0,0,128); @@ -339,6 +394,8 @@ QToolButton:checked, toolButton:checked { color: black; } +/* track label buttons - the part that contains the icon and track title */ + trackLabelButton { background-color: #5b6571; color: #c9c9c9; @@ -354,6 +411,7 @@ trackLabelButton:hover { color: white; border: 1px solid rgba(0,0,0,64); padding: 1px 0px; + margin: 0px; } trackLabelButton:pressed { @@ -380,7 +438,7 @@ trackLabelButton:checked:pressed { background: qlineargradient(spread:reflect, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #49515b, stop:0.3 #5b6571, stop:1 #6b7581 ); } - +/* sidebar, sidebar buttons */ SideBar { background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 #98a2a7, stop: 1.0 #5b646f); @@ -390,13 +448,16 @@ SideBar QToolButton { font-size: 12px; } +/* font sizes for text buttons */ + FxMixerView QPushButton, EffectRackView QPushButton, ControllerRackView QPushButton { font-size: 10px; } -timeLine { +/* has no effect yet */ +/*timeLine { font-size: 8px; -} +}*/ QTreeView { alternate-background-color: #747474; @@ -502,9 +563,3 @@ palette:brighttext {color: #4afd85} palette:highlight {color: #202020} palette:highlightedtext {color: #ffffff} -/* Notes: - -lcd-spinbox colors: (12, 250, 150), (37, 57, 42) - - -*/ diff --git a/data/themes/default/trackop.png b/data/themes/default/trackop.png index dcb8036e2b..bc089652ec 100644 Binary files a/data/themes/default/trackop.png and b/data/themes/default/trackop.png differ diff --git a/data/themes/default/trackop_c.png b/data/themes/default/trackop_c.png index fbd6343ddf..418e4f8eb4 100644 Binary files a/data/themes/default/trackop_c.png and b/data/themes/default/trackop_c.png differ diff --git a/data/themes/default/trackop_h.png b/data/themes/default/trackop_h.png index df1ad5642b..b88839a0d3 100644 Binary files a/data/themes/default/trackop_h.png and b/data/themes/default/trackop_h.png differ diff --git a/data/themes/default/triangle_wave_active.png b/data/themes/default/triangle_wave_active.png index 79a4c6807d..f3ef94abc0 100644 Binary files a/data/themes/default/triangle_wave_active.png and b/data/themes/default/triangle_wave_active.png differ diff --git a/data/themes/default/usr_wave_active.png b/data/themes/default/usr_wave_active.png index 336ca87c6e..2309967d5d 100644 Binary files a/data/themes/default/usr_wave_active.png and b/data/themes/default/usr_wave_active.png differ diff --git a/data/themes/default/white_noise_wave_active.png b/data/themes/default/white_noise_wave_active.png index 8c8fa9d7f8..38b089c63d 100644 Binary files a/data/themes/default/white_noise_wave_active.png and b/data/themes/default/white_noise_wave_active.png differ diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index d725366a4d..1e37cd9b42 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -31,7 +31,7 @@ #include "lmms_basics.h" #include "JournallingObject.h" -#include "midi_time.h" +#include "MidiTime.h" #include "AutomationPattern.h" #include "ComboBoxModel.h" @@ -127,7 +127,7 @@ protected slots: void pasteValues(); void deleteSelectedValues(); - void updatePosition( const midiTime & _t ); + void updatePosition( const MidiTime & _t ); void zoomingXChanged(); void zoomingYChanged(); @@ -218,7 +218,7 @@ private: QScrollBar * m_leftRightScroll; QScrollBar * m_topBottomScroll; - midiTime m_currentPosition; + MidiTime m_currentPosition; actions m_action; @@ -258,7 +258,7 @@ private: signals: void currentPatternChanged(); - void positionChanged( const midiTime & ); + void positionChanged( const MidiTime & ); } ; diff --git a/include/AutomationPattern.h b/include/AutomationPattern.h index 8b11c332c3..ea20bb3a03 100644 --- a/include/AutomationPattern.h +++ b/include/AutomationPattern.h @@ -33,7 +33,7 @@ class AutomationTrack; -class midiTime; +class MidiTime; @@ -72,12 +72,12 @@ public: } void setTension( QString _new_tension ); - virtual midiTime length() const; + virtual MidiTime length() const; - midiTime putValue( const midiTime & _time, const float _value, + MidiTime putValue( const MidiTime & _time, const float _value, const bool _quant_pos = true ); - void removeValue( const midiTime & _time ); + void removeValue( const MidiTime & _time ); inline const timeMap & getTimeMap() const { @@ -104,8 +104,8 @@ public: return m_timeMap.isEmpty() == false; } - float valueAt( const midiTime & _time ) const; - float *valuesAfter( const midiTime & _time ) const; + float valueAt( const MidiTime & _time ) const; + float *valuesAfter( const MidiTime & _time ) const; const QString name() const; @@ -123,7 +123,7 @@ public: return classNodeName(); } - void processMidiTime( const midiTime & _time ); + void processMidiTime( const MidiTime & _time ); virtual trackContentObjectView * createView( trackView * _tv ); diff --git a/include/AutomationTrack.h b/include/AutomationTrack.h index 834174ecea..a4c44b302e 100644 --- a/include/AutomationTrack.h +++ b/include/AutomationTrack.h @@ -36,7 +36,7 @@ public: AutomationTrack( TrackContainer* tc, bool _hidden = false ); virtual ~AutomationTrack(); - virtual bool play( const midiTime & _start, const fpp_t _frames, + virtual bool play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ); virtual QString nodeName() const @@ -45,7 +45,7 @@ public: } virtual trackView * createView( TrackContainerView* ); - virtual trackContentObject * createTCO( const midiTime & _pos ); + virtual trackContentObject * createTCO( const MidiTime & _pos ); virtual void saveTrackSpecificSettings( QDomDocument & _doc, QDomElement & _parent ); diff --git a/include/FileDialog.h b/include/FileDialog.h index ddc2315464..f4d81ea3de 100644 --- a/include/FileDialog.h +++ b/include/FileDialog.h @@ -28,7 +28,9 @@ #include -class FileDialog : public QFileDialog +#include "export.h" + +class EXPORT FileDialog : public QFileDialog { Q_OBJECT public: diff --git a/include/Instrument.h b/include/Instrument.h index 7cec410198..0a840daa3a 100644 --- a/include/Instrument.h +++ b/include/Instrument.h @@ -35,8 +35,8 @@ // forward-declarations class InstrumentTrack; class InstrumentView; -class midiEvent; -class midiTime; +class MidiEvent; +class MidiTime; class notePlayHandle; class track; @@ -99,9 +99,9 @@ public: // sub-classes can re-implement this for receiving all incoming // MIDI-events - inline virtual bool handleMidiEvent( const midiEvent &, const midiTime & ) + inline virtual bool handleMidiEvent( const MidiEvent&, const MidiTime& = MidiTime() ) { - return false; + return true; } virtual QString fullDisplayName() const; diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 3514b0aa75..d4ca720c33 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -34,6 +34,7 @@ #include "note_play_handle.h" #include "Piano.h" #include "PianoView.h" +#include "Pitch.h" #include "track.h" @@ -69,12 +70,10 @@ public: void processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, notePlayHandle * _n ); - midiEvent applyMasterKey( const midiEvent & _me ); + MidiEvent applyMasterKey( const MidiEvent& event ); - virtual void processInEvent( const midiEvent & _me, - const midiTime & _time ); - virtual void processOutEvent( const midiEvent & _me, - const midiTime & _time ); + virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ); + virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ); // silence all running notes played by this track void silenceAllNotes(); @@ -113,17 +112,23 @@ public: // translate pitch to midi-pitch [0,16383] int midiPitch() const { - return (int)( ( m_pitchModel.value()+100 ) * 16383 ) / 200; + return static_cast( ( ( m_pitchModel.value() + m_pitchModel.range()/2 ) * MidiMaxPitchBend ) / m_pitchModel.range() ); + } + + /*! \brief Returns current range for pitch bend in semitones */ + int midiPitchRange() const + { + return m_pitchRangeModel.value(); } // play everything in given frame-range - creates note-play-handles - virtual bool play( const midiTime & _start, const fpp_t _frames, + virtual bool play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ); // create new view for me virtual trackView * createView( TrackContainerView* tcv ); // create new track-content-object = pattern - virtual trackContentObject * createTCO( const midiTime & _pos ); + virtual trackContentObject * createTCO( const MidiTime & _pos ); // called by track @@ -199,8 +204,8 @@ public: signals: void instrumentChanged(); void newNote(); - void noteOn( const note & _n ); - void noteOff( const note & _n ); + void midiNoteOn( const note& ); + void midiNoteOff( const note& ); void nameChanged(); diff --git a/include/midi.h b/include/Midi.h similarity index 53% rename from include/midi.h rename to include/Midi.h index 09a9afa1b9..1b6b69383c 100644 --- a/include/midi.h +++ b/include/Midi.h @@ -1,7 +1,7 @@ /* - * midi.h - constants, structs etc. concerning MIDI + * Midi.h - constants, structs etc. concerning MIDI * - * Copyright (c) 2005-2013 Tobias Doerffel + * Copyright (c) 2005-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -26,8 +26,6 @@ #define _MIDI_H #include "lmms_basics.h" -#include "panning_constants.h" -#include enum MidiEventTypes @@ -60,7 +58,7 @@ enum MidiEventTypes MidiMetaEvent = 0xFF } ; -enum MidiMetaEvents +enum MidiMetaEventTypes { MidiMetaInvalid = 0x00, MidiCopyright = 0x02, @@ -79,6 +77,7 @@ enum MidiMetaEvents MidiMetaCustom = 0x80, MidiNotePanning } ; +typedef MidiMetaEventTypes MidiMetaEventType; enum MidiStandardControllers @@ -88,6 +87,7 @@ enum MidiStandardControllers MidiControllerBreathController = 2, MidiControllerFootController = 4, MidiControllerPortamentoTime = 5, + MidiControllerDataEntry = 6, MidiControllerMainVolume = 7, MidiControllerBalance = 8, MidiControllerPan = 10, @@ -98,6 +98,8 @@ enum MidiStandardControllers MidiControllerSostenuto = 66, MidiControllerSoftPedal = 67, MidiControllerLegatoFootswitch = 68, + MidiControllerRegisteredParameterNumberLSB = 100, + MidiControllerRegisteredParameterNumberMSB = 101, // Channel Mode Messages are controllers too... MidiControllerAllSoundOff = 120, MidiControllerResetAllControllers = 121, @@ -110,6 +112,17 @@ enum MidiStandardControllers }; +enum MidiControllerRegisteredParameterNumbers +{ + MidiPitchBendSensitivityRPN = 0x0000, + MidiChannelFineTuningRPN = 0x0001, + MidiChannelCoarseTuningRPN = 0x0002, + MidiTuningProgramChangeRPN = 0x0003, + MidiTuningBankSelectRPN = 0x0004, + MidiModulationDepthRangeRPN = 0x0005, + MidiNullFunctionNumberRPN = 0x7F7F +}; + const int MidiChannelCount = 16; const int MidiControllerCount = 128; const int MidiProgramCount = 128; @@ -120,139 +133,7 @@ const int MidiMaxNote = 127; const int MidiMaxPanning = 127; const int MidiMinPanning = -128; - -struct midiEvent -{ - midiEvent( MidiEventTypes _type = MidiActiveSensing, - int8_t _channel = 0, - int16_t _param1 = 0, - int16_t _param2 = 0, - const void * _sourcePort = NULL ) : - m_type( _type ), - m_metaEvent( MidiMetaInvalid ), - m_channel( _channel ), - m_sysExData( NULL ), - m_sourcePort( _sourcePort ), - m_fromMidiPort( false ) - { - m_data.m_param[0] = _param1; - m_data.m_param[1] = _param2; - } - - midiEvent( MidiEventTypes _type, const char * _sysex_data, - int _data_len ) : - m_type( _type ), - m_metaEvent( MidiMetaInvalid ), - m_channel( 0 ), - m_sysExData( _sysex_data ), - m_sourcePort( NULL ), - m_fromMidiPort( false ) - { - m_data.m_sysExDataLen = _data_len; - } - - midiEvent( const midiEvent & _copy ) : - m_type( _copy.m_type ), - m_metaEvent( _copy.m_metaEvent ), - m_channel( _copy.m_channel ), - m_data( _copy.m_data ), - m_sysExData( _copy.m_sysExData ), - m_sourcePort( _copy.m_sourcePort ), - m_fromMidiPort( _copy.m_fromMidiPort ) - { - } - - inline MidiEventTypes type() const - { - return m_type; - } - - inline int channel() const - { - return m_channel; - } - - inline int16_t key() const - { - return m_data.m_param[0]; - } - - inline int16_t & key() - { - return m_data.m_param[0]; - } - - inline uint8_t controllerNumber() const - { - return m_data.m_param[0]; - } - - inline uint8_t controllerValue() const - { - return m_data.m_param[1]; - } - - inline int16_t velocity() const - { - return m_data.m_param[1]; - } - - inline int16_t & velocity() - { - return m_data.m_param[1]; - } - - inline int16_t midiPanning() const - { - return m_data.m_param[1]; - } - - inline volume_t getVolume() const - { - return (volume_t)( velocity() * 100 / MidiMaxVelocity ); - } - - inline const void * sourcePort() const - { - return m_sourcePort; - } - - inline panning_t getPanning() const - { - return (panning_t) ( PanningLeft + - ( (float)( midiPanning() - MidiMinPanning ) ) / - ( (float)( MidiMaxPanning - MidiMinPanning ) ) * - ( (float)( PanningRight - PanningLeft ) ) ); - } - - void setFromMidiPort( bool enabled ) - { - m_fromMidiPort = enabled; - } - - bool isFromMidiPort() const - { - return m_fromMidiPort; - } - - MidiEventTypes m_type; // MIDI event type - MidiMetaEvents m_metaEvent; // Meta event (mostly unused) - int8_t m_channel; // MIDI channel - union - { - int16_t m_param[2]; // first/second parameter (key/velocity) - uint8_t m_bytes[4]; // raw bytes - int32_t m_sysExDataLen; // len of m_sysExData - } m_data; - - const char * m_sysExData; - const void * m_sourcePort; - - -private: - bool m_fromMidiPort; - -} ; - +const int MidiMinPitchBend = 0; +const int MidiMaxPitchBend = 16383; #endif diff --git a/include/MidiAlsaSeq.h b/include/MidiAlsaSeq.h index 13d250c3f1..70640ae3a0 100644 --- a/include/MidiAlsaSeq.h +++ b/include/MidiAlsaSeq.h @@ -62,8 +62,8 @@ public: - virtual void processOutEvent( const midiEvent & _me, - const midiTime & _time, + virtual void processOutEvent( const MidiEvent & _me, + const MidiTime & _time, const MidiPort * _port ); virtual void applyPortMode( MidiPort * _port ); @@ -84,7 +84,7 @@ public: } // return name of port which specified MIDI event came from - virtual QString sourcePortName( const midiEvent & ) const; + virtual QString sourcePortName( const MidiEvent & ) const; // (un)subscribe given MidiPort to/from destination-port virtual void subscribeReadablePort( MidiPort * _port, diff --git a/include/MidiClient.h b/include/MidiClient.h index b8f0b459ad..2888999aca 100644 --- a/include/MidiClient.h +++ b/include/MidiClient.h @@ -29,7 +29,7 @@ #include -#include "midi.h" +#include "MidiEvent.h" #include "MidiEventProcessor.h" #include "tab_widget.h" @@ -45,8 +45,8 @@ public: virtual ~MidiClient(); // to be implemented by sub-classes - virtual void processOutEvent( const midiEvent & _me, - const midiTime & _time, + virtual void processOutEvent( const MidiEvent & _me, + const MidiTime & _time, const MidiPort * _port ) = 0; // inheriting classes can re-implement this for being able to update @@ -78,13 +78,13 @@ public: } // return name of port which specified MIDI event came from - virtual QString sourcePortName( const midiEvent & ) const + virtual QString sourcePortName( const MidiEvent & ) const { return QString(); } - // (un)subscribe given MidiPort to/from destination-port + // (un)subscribe given MidiPort to/from destination-port virtual void subscribeReadablePort( MidiPort * _port, const QString & _dest, bool _subscribe = true ); @@ -167,7 +167,7 @@ protected: private: // this does MIDI-event-process void processParsedEvent(); - virtual void processOutEvent( const midiEvent& event, const midiTime& time, const MidiPort* port ); + virtual void processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port ); // small helper function returning length of a certain event - this // is necessary for parsing raw-MIDI-data @@ -188,7 +188,7 @@ private: // event type include? uint32_t m_buffer[RAW_MIDI_PARSE_BUF_SIZE]; // buffer for incoming data - midiEvent m_midiEvent; // midi-event + MidiEvent m_midiEvent; // midi-event } m_midiParseData; } ; diff --git a/include/MidiController.h b/include/MidiController.h index f9d3a0d333..2271e8659f 100644 --- a/include/MidiController.h +++ b/include/MidiController.h @@ -43,11 +43,11 @@ public: MidiController( Model * _parent ); virtual ~MidiController(); - virtual void processInEvent( const midiEvent & _me, - const midiTime & _time ); + virtual void processInEvent( const MidiEvent & _me, + const MidiTime & _time ); - virtual void processOutEvent( const midiEvent& _me, - const midiTime & _time) + virtual void processOutEvent( const MidiEvent& _me, + const MidiTime & _time) { // No output yet } diff --git a/include/MidiEvent.h b/include/MidiEvent.h new file mode 100644 index 0000000000..38bf33f904 --- /dev/null +++ b/include/MidiEvent.h @@ -0,0 +1,209 @@ +/* + * MidiEvent.h - MidiEvent class + * + * Copyright (c) 2005-2014 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef _MIDI_EVENT_H +#define _MIDI_EVENT_H + +#include +#include "Midi.h" +#include "panning_constants.h" + +class MidiEvent +{ +public: + MidiEvent( MidiEventTypes type = MidiActiveSensing, + int8_t channel = 0, + int16_t param1 = 0, + int16_t param2 = 0, + const void* sourcePort = NULL ) : + m_type( type ), + m_metaEvent( MidiMetaInvalid ), + m_channel( channel ), + m_sysExData( NULL ), + m_sourcePort( sourcePort ) + { + m_data.m_param[0] = param1; + m_data.m_param[1] = param2; + } + + MidiEvent( MidiEventTypes type, const char* sysExData, int dataLen ) : + m_type( type ), + m_metaEvent( MidiMetaInvalid ), + m_channel( 0 ), + m_sysExData( sysExData ), + m_sourcePort( NULL ) + { + m_data.m_sysExDataLen = dataLen; + } + + MidiEvent( const MidiEvent& other ) : + m_type( other.m_type ), + m_metaEvent( other.m_metaEvent ), + m_channel( other.m_channel ), + m_data( other.m_data ), + m_sysExData( other.m_sysExData ), + m_sourcePort( other.m_sourcePort ) + { + } + + MidiEventTypes type() const + { + return m_type; + } + + void setType( MidiEventTypes type ) + { + m_type = type; + } + + void setMetaEvent( MidiMetaEventType metaEvent ) + { + m_metaEvent = metaEvent; + } + + MidiMetaEventType metaEvent() const + { + return m_metaEvent; + } + + int8_t channel() const + { + return m_channel; + } + + void setChannel( int8_t channel ) + { + m_channel = channel; + } + + int16_t param( int i ) const + { + return m_data.m_param[i]; + } + + void setParam( int i, uint16_t value ) + { + m_data.m_param[i] = value; + } + + int16_t key() const + { + return param( 0 ); + } + + void setKey( int16_t key ) + { + m_data.m_param[0] = key; + } + + uint8_t velocity() const + { + return m_data.m_param[1] & 0x7F; + } + + void setVelocity( int16_t velocity ) + { + m_data.m_param[1] = velocity; + } + + panning_t panning() const + { + return (panning_t) ( PanningLeft + + ( (float)( midiPanning() - MidiMinPanning ) ) / + ( (float)( MidiMaxPanning - MidiMinPanning ) ) * + ( (float)( PanningRight - PanningLeft ) ) ); + } + int16_t midiPanning() const + { + return m_data.m_param[1]; + } + + volume_t volume() const + { + return (volume_t)( velocity() * 100 / MidiMaxVelocity ); + } + + const void* sourcePort() const + { + return m_sourcePort; + } + + uint8_t controllerNumber() const + { + return param( 0 ) & 0x7F; + } + + void setControllerNumber( uint8_t num ) + { + setParam( 0, num ); + } + + uint8_t controllerValue() const + { + return param( 1 ); + } + + void setControllerValue( uint8_t value ) + { + setParam( 1, value ); + } + + uint8_t program() const + { + return param( 0 ); + } + + uint8_t channelPressure() const + { + return param( 0 ); + } + + int16_t pitchBend() const + { + return param( 0 ); + } + + void setPitchBend( uint16_t pitchBend ) + { + setParam( 0, pitchBend ); + } + + +private: + MidiEventTypes m_type; // MIDI event type + MidiMetaEventType m_metaEvent; // Meta event (mostly unused) + int8_t m_channel; // MIDI channel + union + { + int16_t m_param[2]; // first/second parameter (key/velocity) + uint8_t m_bytes[4]; // raw bytes + int32_t m_sysExDataLen; // len of m_sysExData + } m_data; + + const char* m_sysExData; + const void* m_sourcePort; + +} ; + +#endif diff --git a/include/MidiEventProcessor.h b/include/MidiEventProcessor.h index 1b3d0dd333..dafcfb6cde 100644 --- a/include/MidiEventProcessor.h +++ b/include/MidiEventProcessor.h @@ -25,27 +25,25 @@ #ifndef _MIDI_EVENT_PROCESSOR_H #define _MIDI_EVENT_PROCESSOR_H -class midiEvent; -class midiTime; +#include "MidiEvent.h" +#include "MidiTime.h" // all classes being able to process MIDI-events should inherit from this class MidiEventProcessor { public: - inline MidiEventProcessor() + MidiEventProcessor() { } - virtual inline ~MidiEventProcessor() + virtual ~MidiEventProcessor() { } // to be implemented by inheriting classes - virtual void processInEvent( const midiEvent & _me, - const midiTime & _time ) = 0; - virtual void processOutEvent( const midiEvent & _me, - const midiTime & _time ) = 0; + virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ) = 0; + virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ) = 0; } ; diff --git a/include/MidiPort.h b/include/MidiPort.h index a5b1aee0e0..767dc932e9 100644 --- a/include/MidiPort.h +++ b/include/MidiPort.h @@ -1,8 +1,8 @@ /* - * MidiPort.h - abstraction of MIDI ports which are part of LMMS's MIDI- + * MidiPort.h - abstraction of MIDI ports which are part of LMMS' MIDI * sequencing system * - * Copyright (c) 2005-2009 Tobias Doerffel + * Copyright (c) 2005-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -28,16 +28,17 @@ #include #include -#include +#include -#include "midi.h" +#include "Midi.h" +#include "MidiTime.h" #include "AutomatableModel.h" class MidiClient; +class MidiEvent; class MidiEventProcessor; class MidiPortMenu; -class midiTime; // class for abstraction of MIDI-port @@ -72,67 +73,66 @@ public: Output, // from MIDI-event-processor to MIDI-client Duplex // both directions } ; + typedef Modes Mode; - MidiPort( const QString & _name, - MidiClient * _mc, - MidiEventProcessor * _mep, - Model * _parent = NULL, - Modes _mode = Disabled ); + MidiPort( const QString& name, + MidiClient* client, + MidiEventProcessor* eventProcessor, + Model* parent = NULL, + Mode mode = Disabled ); virtual ~MidiPort(); - void setName( const QString & _name ); + void setName( const QString& name ); - inline Modes mode() const + Mode mode() const { return m_mode; } - void setMode( Modes _mode ); + void setMode( Mode mode ); - inline bool inputEnabled() const + bool isInputEnabled() const { return mode() == Input || mode() == Duplex; } - inline bool outputEnabled() const + bool isOutputEnabled() const { return mode() == Output || mode() == Duplex; } - inline int realOutputChannel() const + int realOutputChannel() const { return outputChannel() - 1; } - void processInEvent( const midiEvent & _me, const midiTime & _time ); - void processOutEvent( const midiEvent & _me, const midiTime & _time ); + void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ); + void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + virtual void saveSettings( QDomDocument& doc, QDomElement& thisElement ); + virtual void loadSettings( const QDomElement& thisElement ); virtual QString nodeName() const { return "midiport"; } - void subscribeReadablePort( const QString & _port, - bool _subscribe = true ); - void subscribeWritablePort( const QString & _port, - bool _subscribe = true ); + void subscribeReadablePort( const QString& port, bool subscribe = true ); + void subscribeWritablePort( const QString& port, bool subscribe = true ); - const Map & readablePorts() const + const Map& readablePorts() const { return m_readablePorts; } - const Map & writablePorts() const + const Map& writablePorts() const { return m_writablePorts; } - MidiPortMenu * m_readablePortsMenu; - MidiPortMenu * m_writablePortsMenu; + MidiPortMenu* m_readablePortsMenu; + MidiPortMenu* m_writablePortsMenu; public slots: @@ -146,10 +146,10 @@ private slots: private: - MidiClient * m_midiClient; - MidiEventProcessor * m_midiEventProcessor; + MidiClient* m_midiClient; + MidiEventProcessor* m_midiEventProcessor; - Modes m_mode; + Mode m_mode; IntModel m_inputChannelModel; IntModel m_outputChannelModel; diff --git a/include/midi_time.h b/include/MidiTime.h similarity index 62% rename from include/midi_time.h rename to include/MidiTime.h index f7f857624e..9a86f3b486 100644 --- a/include/midi_time.h +++ b/include/MidiTime.h @@ -1,8 +1,8 @@ /* - * midi_time.h - declaration of class midiTime which provides data-type for - * position- and length-variables + * MidiTime.h - declaration of class MidiTime which provides data type for + * position- and length-variables * - * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2004-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -35,25 +35,25 @@ const int DefaultStepsPerTact = 16; const int DefaultBeatsPerTact = DefaultTicksPerTact / DefaultStepsPerTact; -class EXPORT midiTime +class EXPORT MidiTime { public: - inline midiTime( const tact_t _tact, const tick_t _ticks ) : - m_ticks( _tact * s_ticksPerTact + _ticks ) + MidiTime( const tact_t tact, const tick_t ticks ) : + m_ticks( tact * s_ticksPerTact + ticks ) { } - inline midiTime( const tick_t _ticks = 0 ) : - m_ticks( _ticks ) + MidiTime( const tick_t ticks = 0 ) : + m_ticks( ticks ) { } - inline midiTime( const midiTime & _t ) : - m_ticks( _t.m_ticks ) + MidiTime( const MidiTime& time ) : + m_ticks( time.m_ticks ) { } - inline midiTime toNearestTact() const + MidiTime toNearestTact() const { if( m_ticks % s_ticksPerTact >= s_ticksPerTact/2 ) { @@ -62,30 +62,30 @@ public: return getTact() * s_ticksPerTact; } - inline midiTime & operator=( const midiTime & _t ) + MidiTime& operator=( const MidiTime& time ) { - m_ticks = _t.m_ticks; + m_ticks = time.m_ticks; return *this; } - inline midiTime & operator+=( const midiTime & _t ) + MidiTime& operator+=( const MidiTime& time ) { - m_ticks += _t.m_ticks; + m_ticks += time.m_ticks; return *this; } - inline midiTime & operator-=( const midiTime & _t ) + MidiTime& operator-=( const MidiTime& time ) { - m_ticks -= _t.m_ticks; + m_ticks -= time.m_ticks; return *this; } - inline tact_t getTact() const + tact_t getTact() const { return m_ticks / s_ticksPerTact; } - inline tact_t nextFullTact() const + tact_t nextFullTact() const { if( m_ticks % s_ticksPerTact == 0 ) { @@ -94,37 +94,34 @@ public: return m_ticks / s_ticksPerTact + 1; } - inline void setTicks( tick_t _t ) + void setTicks( tick_t ticks ) { - m_ticks = _t; + m_ticks = ticks; } - inline tick_t getTicks() const + tick_t getTicks() const { return m_ticks; } - inline operator int() const + operator int() const { return m_ticks; } // calculate number of frame that are needed this time - inline f_cnt_t frames( const float _frames_per_tick ) const + f_cnt_t frames( const float framesPerTick ) const { if( m_ticks >= 0 ) { - return static_cast( m_ticks * - _frames_per_tick ); + return static_cast( m_ticks * framesPerTick ); } return 0; } - static inline midiTime fromFrames( const f_cnt_t _frames, - const float _frames_per_tick ) + static MidiTime fromFrames( const f_cnt_t frames, const float framesPerTick ) { - return midiTime( static_cast( _frames / - _frames_per_tick ) ); + return MidiTime( static_cast( frames / framesPerTick ) ); } @@ -143,6 +140,7 @@ public: s_ticksPerTact = _tpt; } + private: tick_t m_ticks; diff --git a/include/MidiWinMM.h b/include/MidiWinMM.h index 51cccae71c..54b6bdf0de 100644 --- a/include/MidiWinMM.h +++ b/include/MidiWinMM.h @@ -56,8 +56,8 @@ public: - virtual void processOutEvent( const midiEvent & _me, - const midiTime & _time, + virtual void processOutEvent( const MidiEvent & _me, + const MidiTime & _time, const MidiPort * _port ); virtual void applyPortMode( MidiPort * _port ); @@ -78,7 +78,7 @@ public: #endif // return name of port which specified MIDI event came from - virtual QString sourcePortName( const midiEvent & ) const; + virtual QString sourcePortName( const MidiEvent & ) const; // (un)subscribe given MidiPort to/from destination-port virtual void subscribeReadablePort( MidiPort * _port, diff --git a/include/Pitch.h b/include/Pitch.h new file mode 100644 index 0000000000..dc479857ec --- /dev/null +++ b/include/Pitch.h @@ -0,0 +1,38 @@ +/* + * Pitch.h - declaration of some constants and types concerning instrument pitch + * + * Copyright (c) 2014 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef _PITCH_H +#define _PITCH_H + +#include "lmms_basics.h" +#include "Midi.h" + +typedef int16_t pitch_t; + +const pitch_t CentsPerSemitone = 100; +const pitch_t MinPitchDefault = -CentsPerSemitone; +const pitch_t MaxPitchDefault = CentsPerSemitone; +const pitch_t DefaultPitch = 0; + +#endif diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index 46ffc5e150..8eb097ebd4 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -1,7 +1,7 @@ /* * RemotePlugin.h - base class providing RPC like mechanisms * - * Copyright (c) 2008-2012 Tobias Doerffel + * Copyright (c) 2008-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -26,7 +26,7 @@ #define _REMOTE_PLUGIN_H #include "export.h" -#include "midi.h" +#include "MidiEvent.h" #include "VST_sync_shm.h" #include @@ -724,7 +724,7 @@ public: bool process( const sampleFrame * _in_buf, sampleFrame * _out_buf ); - void processMidiEvent( const midiEvent &, const f_cnt_t _offset ); + void processMidiEvent( const MidiEvent&, const f_cnt_t _offset ); void updateSampleRate( sample_rate_t _sr ) { @@ -820,8 +820,7 @@ public: virtual void process( const sampleFrame * _in_buf, sampleFrame * _out_buf ) = 0; - virtual void processMidiEvent( const midiEvent &, - const f_cnt_t /* _offset */ ) + virtual void processMidiEvent( const MidiEvent&, const f_cnt_t /* _offset */ ) { } @@ -1120,7 +1119,7 @@ bool RemotePluginClient::processMessage( const message & _m ) case IdMidiEvent: processMidiEvent( - midiEvent( static_cast( + MidiEvent( static_cast( _m.getInt( 0 ) ), _m.getInt( 1 ), _m.getInt( 2 ), diff --git a/include/SampleRecordHandle.h b/include/SampleRecordHandle.h index 465005fbec..6ff8a3d638 100644 --- a/include/SampleRecordHandle.h +++ b/include/SampleRecordHandle.h @@ -61,7 +61,7 @@ private: typedef QList > bufferList; bufferList m_buffers; f_cnt_t m_framesRecorded; - midiTime m_minLength; + MidiTime m_minLength; track * m_track; bbTrack * m_bbTrack; diff --git a/include/SampleTrack.h b/include/SampleTrack.h index 975ba2477e..fed7856571 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -43,7 +43,7 @@ public: SampleTCO( track * _track ); virtual ~SampleTCO(); - virtual void changeLength( const midiTime & _length ); + virtual void changeLength( const MidiTime & _length ); const QString & sampleFile() const; virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); @@ -58,7 +58,7 @@ public: return m_sampleBuffer; } - midiTime sampleLength() const; + MidiTime sampleLength() const; virtual trackContentObjectView * createView( trackView * _tv ); @@ -121,10 +121,10 @@ public: SampleTrack( TrackContainer* tc ); virtual ~SampleTrack(); - virtual bool play( const midiTime & _start, const fpp_t _frames, + virtual bool play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ); virtual trackView * createView( TrackContainerView* tcv ); - virtual trackContentObject * createTCO( const midiTime & _pos ); + virtual trackContentObject * createTCO( const MidiTime & _pos ); virtual void saveTrackSpecificSettings( QDomDocument & _doc, diff --git a/include/TrackContainerView.h b/include/TrackContainerView.h index 2203fb8683..a18bf5a78e 100644 --- a/include/TrackContainerView.h +++ b/include/TrackContainerView.h @@ -56,7 +56,7 @@ public: return( m_scrollArea ); } - inline const midiTime & currentPosition() const + inline const MidiTime & currentPosition() const { return( m_currentPosition ); } @@ -142,7 +142,7 @@ protected: virtual void undoStep( JournalEntry & _je ); virtual void redoStep( JournalEntry & _je ); - midiTime m_currentPosition; + MidiTime m_currentPosition; private: @@ -180,7 +180,7 @@ private: signals: - void positionChanged( const midiTime & _pos ); + void positionChanged( const MidiTime & _pos ); } ; diff --git a/include/aeffectx.h b/include/aeffectx.h index 393249b033..4188bf41a8 100644 --- a/include/aeffectx.h +++ b/include/aeffectx.h @@ -175,7 +175,7 @@ public: // 04 void *reserved; // 08 - VstEvent * events[]; + VstEvent* events[1]; } ; diff --git a/include/bb_track.h b/include/bb_track.h index 8b0dbff99f..a4c440f4c9 100644 --- a/include/bb_track.h +++ b/include/bb_track.h @@ -109,10 +109,10 @@ public: bbTrack( TrackContainer* tc ); virtual ~bbTrack(); - virtual bool play( const midiTime & _start, const fpp_t _frames, + virtual bool play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ); virtual trackView * createView( TrackContainerView* tcv ); - virtual trackContentObject * createTCO( const midiTime & _pos ); + virtual trackContentObject * createTCO( const MidiTime & _pos ); virtual void saveTrackSpecificSettings( QDomDocument & _doc, QDomElement & _parent ); diff --git a/include/bb_track_container.h b/include/bb_track_container.h index bc9bf70645..3ad0b91572 100644 --- a/include/bb_track_container.h +++ b/include/bb_track_container.h @@ -38,7 +38,7 @@ public: bbTrackContainer(); virtual ~bbTrackContainer(); - virtual bool play( midiTime _start, const fpp_t _frames, + virtual bool play( MidiTime _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ); virtual void updateAfterTrackAdd(); diff --git a/include/note.h b/include/note.h index 36bf1640de..199254f9d0 100644 --- a/include/note.h +++ b/include/note.h @@ -30,7 +30,7 @@ #include "volume.h" #include "panning.h" -#include "midi_time.h" +#include "MidiTime.h" #include "SerializingObject.h" class DetuningHelper; @@ -81,8 +81,8 @@ const float MaxDetuning = 4 * 12.0f; class EXPORT note : public SerializingObject { public: - note( const midiTime & _length = midiTime( 0 ), - const midiTime & _pos = midiTime( 0 ), + note( const MidiTime & _length = MidiTime( 0 ), + const MidiTime & _pos = MidiTime( 0 ), int key = DefaultKey, volume_t _volume = DefaultVolume, panning_t _panning = DefaultPanning, @@ -93,8 +93,8 @@ public: // used by GUI inline void setSelected( const bool _selected ){ m_selected = _selected; } inline void setOldKey( const int _oldKey ){ m_oldKey = _oldKey; } - inline void setOldPos( const midiTime & _oldPos ){ m_oldPos = _oldPos; } - inline void setOldLength( const midiTime & _oldLength ) + inline void setOldPos( const MidiTime & _oldPos ){ m_oldPos = _oldPos; } + inline void setOldLength( const MidiTime & _oldLength ) { m_oldLength = _oldLength; } @@ -104,11 +104,11 @@ public: } - void setLength( const midiTime & _length ); - void setPos( const midiTime & _pos ); + void setLength( const MidiTime & _length ); + void setPos( const MidiTime & _pos ); void setKey( const int _key ); - virtual void setVolume( const volume_t _volume = DefaultVolume ); - void setPanning( const panning_t _panning = DefaultPanning ); + virtual void setVolume( const volume_t volume = DefaultVolume ); + virtual void setPanning( const panning_t panning = DefaultPanning ); void quantizeLength( const int _q_grid ); void quantizePos( const int _q_grid ); @@ -129,12 +129,12 @@ public: return m_oldKey; } - inline midiTime oldPos() const + inline MidiTime oldPos() const { return m_oldPos; } - inline midiTime oldLength() const + inline MidiTime oldLength() const { return m_oldLength; } @@ -144,23 +144,23 @@ public: return m_isPlaying; } - inline midiTime endPos() const + inline MidiTime endPos() const { const int l = length(); return pos() + l; } - inline const midiTime & length() const + inline const MidiTime & length() const { return m_length; } - inline const midiTime & pos() const + inline const MidiTime & pos() const { return m_pos; } - inline midiTime pos( midiTime _base_pos ) const + inline MidiTime pos( MidiTime _base_pos ) const { const int bp = _base_pos; return m_pos - bp; @@ -191,7 +191,7 @@ public: return classNodeName(); } - static midiTime quantized( const midiTime & _m, const int _q_grid ); + static MidiTime quantized( const MidiTime & _m, const int _q_grid ); DetuningHelper * detuning() const { @@ -226,15 +226,15 @@ private: // for piano roll editing bool m_selected; int m_oldKey; - midiTime m_oldPos; - midiTime m_oldLength; + MidiTime m_oldPos; + MidiTime m_oldLength; bool m_isPlaying; int m_key; volume_t m_volume; panning_t m_panning; - midiTime m_length; - midiTime m_pos; + MidiTime m_length; + MidiTime m_pos; DetuningHelper * m_detuning; void createDetuning(); diff --git a/include/note_play_handle.h b/include/note_play_handle.h index 2c2b2e3f1f..9c22eea3be 100644 --- a/include/note_play_handle.h +++ b/include/note_play_handle.h @@ -2,7 +2,7 @@ * note_play_handle.h - declaration of class notePlayHandle which is needed * by LMMS-Play-Engine * - * Copyright (c) 2004-2012 Tobias Doerffel + * Copyright (c) 2004-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -48,17 +48,33 @@ public: void * m_pluginData; basicFilters<> * m_filter; + // specifies origin of NotePlayHandle + enum Origins + { + OriginPattern, /*! playback of a note from a pattern */ + OriginMidiInput, /*! playback of a MIDI note input event */ + OriginCount + }; + typedef Origins Origin; + notePlayHandle( InstrumentTrack * _instrument_track, const f_cnt_t _offset, const f_cnt_t _frames, const note & _n, notePlayHandle * _parent = NULL, - const bool _part_of_arp = false ); + const bool _part_of_arp = false, + int midiEventChannel = -1, + Origin origin = OriginPattern ); virtual ~notePlayHandle(); - virtual void setVolume( const volume_t _volume = DefaultVolume ); + virtual void setVolume( const volume_t volume = DefaultVolume ); + virtual void setPanning( const panning_t panning = DefaultPanning ); int midiVelocity() const; int midiKey() const; + int midiChannel() const + { + return m_midiChannel; + } const float & frequency() const { @@ -189,15 +205,15 @@ public: m_bbTrack = _bb_track; } - void processMidiTime( const midiTime & _time ); + void processMidiTime( const MidiTime & _time ); void resize( const bpm_t _new_tempo ); - void setSongGlobalParentOffset( const midiTime &offset ) + void setSongGlobalParentOffset( const MidiTime &offset ) { m_songGlobalParentOffset = offset; } - const midiTime &songGlobalParentOffset() const + const MidiTime &songGlobalParentOffset() const { return m_songGlobalParentOffset; } @@ -266,13 +282,16 @@ private: bpm_t m_origTempo; // original tempo f_cnt_t m_origFrames; // original m_frames - int m_origBaseNote; + const int m_origBaseNote; float m_frequency; float m_unpitchedFrequency; BaseDetuning * m_baseDetuning; - midiTime m_songGlobalParentOffset; + MidiTime m_songGlobalParentOffset; + + const int m_midiChannel; + const Origin m_origin; } ; diff --git a/include/panning.h b/include/panning.h index 29d2e5365b..60188e3f84 100644 --- a/include/panning.h +++ b/include/panning.h @@ -2,7 +2,7 @@ * panning.h - declaration of some types, concerning the * panning of a note * - * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2004-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -30,7 +30,7 @@ #include "volume.h" #include "templates.h" #include "panning_constants.h" -#include "midi.h" +#include "Midi.h" inline stereoVolumeVector panningToVolumeVector( panning_t _p, float _scale = 1.0f ) diff --git a/include/pattern.h b/include/pattern.h index 26b51849e3..fcb66fed9b 100644 --- a/include/pattern.h +++ b/include/pattern.h @@ -64,8 +64,8 @@ public: void init(); - virtual midiTime length() const; - midiTime beatPatternLength() const; + virtual MidiTime length() const; + MidiTime beatPatternLength() const; // note management note * addNote( const note & _new_note, const bool _quant_pos = true ); diff --git a/include/piano_roll.h b/include/piano_roll.h index 55e193b992..596a29f1af 100644 --- a/include/piano_roll.h +++ b/include/piano_roll.h @@ -135,8 +135,8 @@ protected slots: void pasteNotes(); void deleteSelectedNotes(); - void updatePosition( const midiTime & _t ); - void updatePositionAccompany( const midiTime & _t ); + void updatePosition( const MidiTime & _t ); + void updatePositionAccompany( const MidiTime & _t ); void zoomingChanged(); void quantizeChanged(); @@ -203,9 +203,9 @@ private: pianoRoll( const pianoRoll & ); virtual ~pianoRoll(); - void autoScroll( const midiTime & _t ); + void autoScroll( const MidiTime & _t ); - midiTime newNoteLen() const; + MidiTime newNoteLen() const; void shiftPos(int amount); void shiftSemiTone(int amount); @@ -276,7 +276,7 @@ private: QScrollBar * m_leftRightScroll; QScrollBar * m_topBottomScroll; - midiTime m_currentPosition; + MidiTime m_currentPosition; bool m_recording; QList m_recordingNotes; @@ -315,7 +315,7 @@ private: // remember these values to use them // for the next note that is set - midiTime m_lenOfNewNotes; + MidiTime m_lenOfNewNotes; volume_t m_lastNoteVolume; panning_t m_lastNotePanning; @@ -345,7 +345,7 @@ private: signals: - void positionChanged( const midiTime & ); + void positionChanged( const MidiTime & ); } ; diff --git a/include/preset_preview_play_handle.h b/include/preset_preview_play_handle.h index 3e4d4e53c5..abef2c78ba 100644 --- a/include/preset_preview_play_handle.h +++ b/include/preset_preview_play_handle.h @@ -2,7 +2,7 @@ * preset_preview_play_handle.h - play-handle for playing a short preview-sound * of a preset or a file processed by a plugin * - * Copyright (c) 2005-2008 Tobias Doerffel + * Copyright (c) 2005-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -34,7 +34,7 @@ class InstrumentTrack; class previewTrackContainer; -class presetPreviewPlayHandle : public playHandle +class EXPORT presetPreviewPlayHandle : public playHandle { public: presetPreviewPlayHandle( const QString & _preset_file, @@ -51,6 +51,8 @@ public: static ConstNotePlayHandleList nphsOfInstrumentTrack( const InstrumentTrack * _ct ); + static bool isPreviewing(); + private: static previewTrackContainer * s_previewTC; diff --git a/include/setup_dialog.h b/include/setup_dialog.h index f5bd006762..53c2be08f0 100644 --- a/include/setup_dialog.h +++ b/include/setup_dialog.h @@ -1,7 +1,7 @@ /* * setup_dialog.h - dialog for setting up LMMS * - * Copyright (c) 2005-2011 Tobias Doerffel + * Copyright (c) 2005-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -102,8 +102,6 @@ private slots: void openDefaultSoundfont(); void openBackgroundArtwork(); - void toggleDisableChActInd( bool _disabled ); - void toggleManualChPiano( bool _enabled ); void toggleSmoothScroll( bool _enabled ); void toggleAutoSave( bool _enabled ); void toggleOneInstrumentTrackWindow( bool _enabled ); @@ -154,8 +152,6 @@ private: #endif QString m_backgroundArtwork; - bool m_disableChActInd; - bool m_manualChPiano; bool m_smoothScroll; bool m_enableAutoSave; bool m_oneInstrumentTrackWindow; diff --git a/include/song.h b/include/song.h index ed6c188724..32b36e34b1 100644 --- a/include/song.h +++ b/include/song.h @@ -65,11 +65,11 @@ public: } ; - class playPos : public midiTime + class playPos : public MidiTime { public: playPos( const int _abs = 0 ) : - midiTime( _abs ), + MidiTime( _abs ), m_timeLine( NULL ), m_timeLineUpdate( true ), m_currentFrame( 0.0f ) diff --git a/include/song_editor.h b/include/song_editor.h index 9896367900..af10cd51cf 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -84,7 +84,7 @@ private slots: void masterPitchReleased(); void updateScrollBar( int ); - void updatePosition( const midiTime & _t ); + void updatePosition( const MidiTime & _t ); void zoomingChanged(); diff --git a/include/timeline.h b/include/timeline.h index 298f42a7ba..ff46618370 100644 --- a/include/timeline.h +++ b/include/timeline.h @@ -61,7 +61,7 @@ public: timeLine( int _xoff, int _yoff, float _ppt, song::playPos & _pos, - const midiTime & _begin, QWidget * _parent ); + const MidiTime & _begin, QWidget * _parent ); virtual ~timeLine(); inline song::playPos & pos() @@ -84,23 +84,23 @@ public: return m_loopPoints == LoopPointsEnabled; } - inline const midiTime & loopBegin() const + inline const MidiTime & loopBegin() const { return ( m_loopPos[0] < m_loopPos[1] ) ? m_loopPos[0] : m_loopPos[1]; } - inline const midiTime & loopEnd() const + inline const MidiTime & loopEnd() const { return ( m_loopPos[0] > m_loopPos[1] ) ? m_loopPos[0] : m_loopPos[1]; } - inline void savePos( const midiTime & _pos ) + inline void savePos( const MidiTime & _pos ) { m_savedPos = _pos; } - inline const midiTime & savedPos() const + inline const MidiTime & savedPos() const { return m_savedPos; } @@ -121,18 +121,18 @@ public: return "timeline"; } - inline int markerX( const midiTime & _t ) const + inline int markerX( const MidiTime & _t ) const { return m_xOffset + static_cast( ( _t - m_begin ) * - m_ppt / midiTime::ticksPerTact() ); + m_ppt / MidiTime::ticksPerTact() ); } public slots: - void updatePosition( const midiTime & ); + void updatePosition( const MidiTime & ); void updatePosition() { - updatePosition( midiTime() ); + updatePosition( MidiTime() ); } void toggleAutoScroll( int _n ); void toggleLoopPoints( int _n ); @@ -162,10 +162,10 @@ private: int m_posMarkerX; float m_ppt; song::playPos & m_pos; - const midiTime & m_begin; - midiTime m_loopPos[2]; + const MidiTime & m_begin; + MidiTime m_loopPos[2]; - midiTime m_savedPos; + MidiTime m_savedPos; textFloat * m_hint; @@ -183,7 +183,7 @@ private: signals: - void positionChanged( const midiTime & _t ); + void positionChanged( const MidiTime & _t ); void loopPointStateLoaded( int _n ); } ; diff --git a/include/track.h b/include/track.h index cbb5faaebb..e30e62e485 100644 --- a/include/track.h +++ b/include/track.h @@ -31,7 +31,7 @@ #include #include "lmms_basics.h" -#include "midi_time.h" +#include "MidiTime.h" #include "rubberband.h" #include "JournallingObject.h" #include "AutomatableModel.h" @@ -101,24 +101,24 @@ public: } - inline const midiTime & startPosition() const + inline const MidiTime & startPosition() const { return m_startPosition; } - inline midiTime endPosition() const + inline MidiTime endPosition() const { const int sp = m_startPosition; return sp + m_length; } - inline const midiTime & length() const + inline const MidiTime & length() const { return m_length; } - virtual void movePosition( const midiTime & _pos ); - virtual void changeLength( const midiTime & _length ); + virtual void movePosition( const MidiTime & _pos ); + virtual void changeLength( const MidiTime & _length ); virtual trackContentObjectView * createView( trackView * _tv ) = 0; @@ -151,8 +151,8 @@ private: track * m_track; QString m_name; - midiTime m_startPosition; - midiTime m_length; + MidiTime m_startPosition; + MidiTime m_length; BoolModel m_mutedModel; BoolModel m_soloModel; @@ -230,7 +230,7 @@ private: textFloat * m_hint; - midiTime m_oldTime;// used for undo/redo while mouse-button is pressed + MidiTime m_oldTime;// used for undo/redo while mouse-button is pressed } ; @@ -258,11 +258,11 @@ public: } } - midiTime endPosition( const midiTime & _pos_start ); + MidiTime endPosition( const MidiTime & _pos_start ); public slots: void update(); - void changePosition( const midiTime & _new_pos = midiTime( -1 ) ); + void changePosition( const MidiTime & _new_pos = MidiTime( -1 ) ); protected: @@ -289,7 +289,7 @@ private: } ; track * getTrack(); - midiTime getPosition( int _mouse_x ); + MidiTime getPosition( int _mouse_x ); trackView * m_trackView; @@ -382,12 +382,12 @@ public: return m_type; } - virtual bool play( const midiTime & _start, const fpp_t _frames, + virtual bool play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ) = 0; virtual trackView * createView( TrackContainerView * _view ) = 0; - virtual trackContentObject * createTCO( const midiTime & _pos ) = 0; + virtual trackContentObject * createTCO( const MidiTime & _pos ) = 0; virtual void saveTrackSpecificSettings( QDomDocument & _doc, QDomElement & _parent ) = 0; @@ -415,13 +415,13 @@ public: { return( m_trackContentObjects ); } - void getTCOsInRange( tcoVector & _tco_v, const midiTime & _start, - const midiTime & _end ); + void getTCOsInRange( tcoVector & _tco_v, const MidiTime & _start, + const MidiTime & _end ); void swapPositionOfTCOs( int _tco_num1, int _tco_num2 ); - void insertTact( const midiTime & _pos ); - void removeTact( const midiTime & _pos ); + void insertTact( const MidiTime & _pos ); + void removeTact( const MidiTime & _pos ); tact_t length() const; diff --git a/include/volume.h b/include/volume.h index aeb1daf1c2..dedecd504c 100644 --- a/include/volume.h +++ b/include/volume.h @@ -2,7 +2,7 @@ * volume.h - declaration of some constants and types, concerning the volume * of a note * - * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2004-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -29,7 +29,7 @@ #include "lmmsconfig.h" #include "lmms_basics.h" -#include "midi.h" +#include "Midi.h" const volume_t MinVolume = 0; const volume_t MaxVolume = 200; diff --git a/plugins/flp_import/FlpImport.cpp b/plugins/flp_import/FlpImport.cpp index c374595f86..c238fee100 100644 --- a/plugins/flp_import/FlpImport.cpp +++ b/plugins/flp_import/FlpImport.cpp @@ -1744,8 +1744,7 @@ p->putValue( jt->pos, value, false ); { continue; } - trackContentObject * tco = - bb_tracks[it->pattern]->createTCO( midiTime() ); + trackContentObject * tco = bb_tracks[it->pattern]->createTCO( MidiTime() ); tco->movePosition( it->position ); if( it->length != DefaultTicksPerTact ) { diff --git a/plugins/ladspa_effect/cmt/src/init.cpp b/plugins/ladspa_effect/cmt/src/init.cpp index 76a7b2634d..f232840fa9 100644 --- a/plugins/ladspa_effect/cmt/src/init.cpp +++ b/plugins/ladspa_effect/cmt/src/init.cpp @@ -108,18 +108,26 @@ public: finalise_modules(); } -} g_oStartupShutdownHandler; +} ; /*****************************************************************************/ +extern "C" +{ + const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index) { + + static StartupShutdownHandler handler; + if (Index < g_lPluginCount) return g_ppsRegisteredDescriptors[Index]; else return NULL; } +}; + /*****************************************************************************/ /* EOF */ diff --git a/plugins/ladspa_effect/swh/CMakeLists.txt b/plugins/ladspa_effect/swh/CMakeLists.txt index 85621c5dc3..5a3e3d0e4b 100644 --- a/plugins/ladspa_effect/swh/CMakeLists.txt +++ b/plugins/ladspa_effect/swh/CMakeLists.txt @@ -29,8 +29,14 @@ FOREACH(_item ${PLUGIN_SOURCES}) ENDFOREACH(_item ${PLUGIN_SOURCES}) +IF(LMMS_BUILD_WIN32) + SET(PIC_FLAGS "") +ELSE(LMMS_BUILD_WIN32) + SET(PIC_FLAGS "-fPIC") +ENDIF(LMMS_BUILD_WIN32) + ADD_LIBRARY(iir STATIC util/iir.c) -SET_TARGET_PROPERTIES(iir PROPERTIES COMPILE_FLAGS "-fPIC") +SET_TARGET_PROPERTIES(iir PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(bandpass_a_iir_1893 iir) TARGET_LINK_LIBRARIES(bandpass_iir_1892 iir) TARGET_LINK_LIBRARIES(butterworth_1902 iir) @@ -40,21 +46,21 @@ TARGET_LINK_LIBRARIES(notch_iir_1894 iir) FILE(GLOB GSM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/gsm/*.c) ADD_LIBRARY(gsm STATIC ${GSM_SOURCES}) -SET_TARGET_PROPERTIES(gsm PROPERTIES COMPILE_FLAGS "-fPIC") +SET_TARGET_PROPERTIES(gsm PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(gsm_1215 gsm) ADD_LIBRARY(gverb STATIC gverb/gverb.c gverb/gverbdsp.c) -SET_TARGET_PROPERTIES(gverb PROPERTIES COMPILE_FLAGS "-fPIC") +SET_TARGET_PROPERTIES(gverb PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(gverb_1216 gverb) ADD_LIBRARY(blo STATIC util/blo.c) -SET_TARGET_PROPERTIES(blo PROPERTIES COMPILE_FLAGS "-fPIC") +SET_TARGET_PROPERTIES(blo PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(hermes_filter_1200 blo) ADD_LIBRARY(rms STATIC util/rms.c) ADD_LIBRARY(db STATIC util/db.c) -SET_TARGET_PROPERTIES(rms PROPERTIES COMPILE_FLAGS "-fPIC") -SET_TARGET_PROPERTIES(db PROPERTIES COMPILE_FLAGS "-fPIC") +SET_TARGET_PROPERTIES(rms PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") +SET_TARGET_PROPERTIES(db PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(sc1_1425 rms db) TARGET_LINK_LIBRARIES(sc2_1426 rms db) TARGET_LINK_LIBRARIES(sc3_1427 rms db) @@ -63,6 +69,6 @@ TARGET_LINK_LIBRARIES(sc4m_1916 rms db) TARGET_LINK_LIBRARIES(se4_1883 rms db) ADD_LIBRARY(pitchscale STATIC util/pitchscale.c) -SET_TARGET_PROPERTIES(pitchscale PROPERTIES COMPILE_FLAGS "-fPIC") +SET_TARGET_PROPERTIES(pitchscale PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") TARGET_LINK_LIBRARIES(pitch_scale_1193 pitchscale) TARGET_LINK_LIBRARIES(pitch_scale_1194 pitchscale) diff --git a/plugins/ladspa_effect/swh/util/blo.c b/plugins/ladspa_effect/swh/util/blo.c index b2d05218d3..9524d0e87a 100644 --- a/plugins/ladspa_effect/swh/util/blo.c +++ b/plugins/ladspa_effect/swh/util/blo.c @@ -48,7 +48,9 @@ blo_h_tables *blo_h_tables_new(int table_size) unsigned int h; size_t all_tables_size = sizeof(float) * (table_size + BLO_TABLE_WR) * (BLO_N_HARMONICS - 1) * 2; +#ifndef WIN32 int shm_fd; +#endif char shm_path[128]; this = malloc(sizeof(blo_h_tables)); diff --git a/plugins/ladspa_effect/swh/vocoder_1337.c b/plugins/ladspa_effect/swh/vocoder_1337.c new file mode 100644 index 0000000000..086faffb55 --- /dev/null +++ b/plugins/ladspa_effect/swh/vocoder_1337.c @@ -0,0 +1,456 @@ +/* vocoder.c + Version 0.3 + + LADSPA Unique ID: 1337 + + Version 0.31 + Added stereo output, renamed input/output ports, added, + added a control for stereo balance + + Version 0.3 + Added support for changing bands in real time 2003-12-09 + + Version 0.2 + Adapted to LADSPA by Josh Green + 15.6.2001 (for the LinuxTag 2001!) + + Original program can be found at: + http://www.sirlab.de/linux/ + Author: Achim Settelmeier + + Adapted to LMMS by Hexasoft (hexasoft.corp@free.fr) + + + Licence: GPL + 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 . + +*/ + + +/* not familiar with WINDOWS stuff. Saw this in other sources, it should be needed */ + +#ifdef WIN32 +#define _WINDOWS_DLL_EXPORT_ __declspec(dllexport) +int bIsFirstTime = 1; +void _init(); // forward declaration +#else +#define _WINDOWS_DLL_EXPORT_ +#endif + + +/*****************************************************************************/ +/* general includes */ +#include +#include +#include +#include + +/*****************************************************************************/ +/* LADSPA headers */ +#include + +/*****************************************************************************/ + + +#define LADSPA_UNIQUE_ID 1337 + +#define MAX_BANDS 16 /* max 16 bandsn should be increased */ +#define AMPLIFIER 16.0 + +struct bandpass +{ + LADSPA_Data c, f, att; + + LADSPA_Data freq; + LADSPA_Data low1, low2; + LADSPA_Data mid1, mid2; + LADSPA_Data high1, high2; + LADSPA_Data y; +}; + +struct bands_out{ + LADSPA_Data decay; + LADSPA_Data oldval; + LADSPA_Data level; /* 0.0 - 1.0 level of this output band */ +}; + +const LADSPA_Data decay_table[] = +{ + 1/100.0, + 1/100.0, 1/100.0, 1/100.0, + 1/125.0, 1/125.0, 1/125.0, + 1/166.0, 1/166.0, 1/166.0, + 1/200.0, 1/200.0, 1/200.0, + 1/250.0, 1/250.0, 1/250.0 +}; + +/* The port numbers for the plugin: */ + +#define PORT_FORMANT 0 /* the track to "vocodify */ +#define PORT_CARRIER 1 /* the track to control 1st track */ +#define PORT_OUTPUT 2 /* left output */ +#define PORT_OUTPUT2 3 /* right output */ +#define CTRL_BANDCOUNT 4 /* selected # of bands to use */ +#define CTRL_PAN 5 /* stereo balance for outputs */ +#define CTRL_BAND1LVL 6 /* start of bands level */ + +#define PORT_COUNT 6 + MAX_BANDS /* bands level */ + + +/* useful macros */ +#undef CLAMP +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +/* Instance data for the vocoder plugin */ +typedef struct { + LADSPA_Data SampleRate; + + int num_bands; /* current number of bands */ + float mainvol; /* main volume */ + + struct bandpass bands_formant[MAX_BANDS]; /* one structure per band */ + struct bandpass bands_carrier[MAX_BANDS]; /* one structure per band */ + struct bands_out bands_out[MAX_BANDS]; /* one structure per band */ + + /* Ports */ + + LADSPA_Data * portFormant; /* Formant signal port data location */ + LADSPA_Data * portCarrier; /* Carrier signal port data location */ + LADSPA_Data * portOutput; /* Output audio port data location */ + LADSPA_Data * portOutput2; /* Output audio port data location (copy of previous one) */ + LADSPA_Data * ctrlPan; /* PAN for output */ + LADSPA_Data * ctrlBandCount; /* Band count control */ + LADSPA_Data * ctrlBandLevels[MAX_BANDS]; /* level controls for each band */ + +} VocoderInstance; + +/*****************************************************************************/ + +/* Construct a new plugin instance. */ +LADSPA_Handle +instantiateVocoder(const LADSPA_Descriptor * Descriptor, + unsigned long SampleRate) { + VocoderInstance * vocoder; + + vocoder = (VocoderInstance *)malloc(sizeof(VocoderInstance)); + + if (vocoder == NULL) + return NULL; + + vocoder->SampleRate = (LADSPA_Data)SampleRate; + vocoder->num_bands = -1; + + return vocoder; +} + +/*****************************************************************************/ + +/* Initialise and activate a plugin instance. */ +void +activateVocoder(LADSPA_Handle Instance) { + VocoderInstance *vocoder = (VocoderInstance *)Instance; + int i; + + vocoder->mainvol = 1.0 * AMPLIFIER; + + for (i = 0; i < MAX_BANDS; i++) + vocoder->bands_out[i].oldval = 0.0; +} + +/*****************************************************************************/ + +/* Connect a port to a data location. */ +void +connectPortToVocoder(LADSPA_Handle Instance, + unsigned long Port, + LADSPA_Data * DataLocation) { + + VocoderInstance * vocoder; + + vocoder = (VocoderInstance *)Instance; + switch (Port) { + case PORT_FORMANT: /* formant port? */ + vocoder->portFormant = DataLocation; + break; + case PORT_CARRIER: /* carrier port? */ + vocoder->portCarrier = DataLocation; + break; + case PORT_OUTPUT: /* output port? */ + vocoder->portOutput = DataLocation; + break; + case PORT_OUTPUT2: /* output port? */ + vocoder->portOutput2 = DataLocation; + break; + case CTRL_BANDCOUNT: /* band count control? */ + vocoder->ctrlBandCount = DataLocation; + break; + case CTRL_PAN: /* Pan control? */ + vocoder->ctrlPan = DataLocation; + break; + default: /* a band level control? */ + if (Port >= CTRL_BAND1LVL && Port < CTRL_BAND1LVL + MAX_BANDS) + vocoder->ctrlBandLevels[Port - CTRL_BAND1LVL] = DataLocation; + break; + } +} + +/*****************************************************************************/ + +// vocoder_do_bandpasses /*fold00*/ +void vocoder_do_bandpasses(struct bandpass *bands, LADSPA_Data sample, + VocoderInstance *vocoder) +{ + int i; + for (i=0; i < vocoder->num_bands; i++) + { + bands[i].high1 = sample - bands[i].f * bands[i].mid1 - bands[i].low1; + bands[i].mid1 += bands[i].high1 * bands[i].c; + bands[i].low1 += bands[i].mid1; + + bands[i].high2 = bands[i].low1 - bands[i].f * bands[i].mid2 + - bands[i].low2; + bands[i].mid2 += bands[i].high2 * bands[i].c; + bands[i].low2 += bands[i].mid2; + bands[i].y = bands[i].high2 * bands[i].att; + } +} + +/* Run a vocoder instance for a block of SampleCount samples. */ +void +runVocoder(LADSPA_Handle Instance, + unsigned long SampleCount) +{ + VocoderInstance *vocoder = (VocoderInstance *)Instance; + int i, j, numbands, pan; + float a; + LADSPA_Data x, c; + float fl, fr; + + numbands = (int)(*vocoder->ctrlBandCount); + if (numbands < 1 || numbands > MAX_BANDS) numbands = MAX_BANDS; + + /* initialize bandpass information if num_bands control has changed, + or on first run */ + if (vocoder->num_bands != numbands) + { + vocoder->num_bands = numbands; + + for(i=0; i < numbands; i++) + { + memset(&vocoder->bands_formant[i], 0, sizeof(struct bandpass)); + + a = 16.0 * i/(double)numbands; // stretch existing bands + + if (a < 4.0) + vocoder->bands_formant[i].freq = 150 + 420 * a / 4.0; + else + vocoder->bands_formant[i].freq = 600 * pow (1.23, a - 4.0); + + c = vocoder->bands_formant[i].freq * 2 * M_PI / vocoder->SampleRate; + vocoder->bands_formant[i].c = c * c; + + vocoder->bands_formant[i].f = 0.4/c; + vocoder->bands_formant[i].att = + 1/(6.0 + ((exp (vocoder->bands_formant[i].freq + / vocoder->SampleRate) - 1) * 10)); + + memcpy(&vocoder->bands_carrier[i], + &vocoder->bands_formant[i], sizeof(struct bandpass)); + + vocoder->bands_out[i].decay = decay_table[(int)a]; + vocoder->bands_out[i].level = + CLAMP (*vocoder->ctrlBandLevels[i], 0.0, 1.0); + } + } + else /* get current values of band level controls */ + { + for (i = 0; i < numbands; i++) + vocoder->bands_out[i].level = CLAMP (*vocoder->ctrlBandLevels[i], + 0.0, 1.0); + } + + for (i=0; i < SampleCount; i++) + { + vocoder_do_bandpasses (vocoder->bands_carrier, + vocoder->portCarrier[i], vocoder); + vocoder_do_bandpasses (vocoder->bands_formant, + vocoder->portFormant[i], vocoder); + + vocoder->portOutput[i] = 0.0; + vocoder->portOutput2[i] = 0.0; + for (j=0; j < numbands; j++) + { + vocoder->bands_out[j].oldval = vocoder->bands_out[j].oldval + + (fabs (vocoder->bands_formant[j].y) + - vocoder->bands_out[j].oldval) + * vocoder->bands_out[j].decay; + x = vocoder->bands_carrier[j].y * vocoder->bands_out[j].oldval; + vocoder->portOutput[i] += x * vocoder->bands_out[j].level; + vocoder->portOutput2[i] += x * vocoder->bands_out[j].level; + } + /* treat paning + main volume */ + pan = (int)(*vocoder->ctrlPan); + fl = fr = 1.; + if (pan != 0) { /* no paning, don't compute useless values */ + if (pan > 0) { /* reduce left */ + fl = (100.-pan)/100.; + } else { + fr = (100.+pan)/100.; + } + } + /* apply volume and paning */ + vocoder->portOutput[i] *= vocoder->mainvol * fl; + vocoder->portOutput2[i] *= vocoder->mainvol * fr; + } +} + + +/*****************************************************************************/ + +/* Throw away a vocoder instance. */ +void +cleanupVocoder(LADSPA_Handle Instance) +{ + VocoderInstance * Vocoder; + Vocoder = (VocoderInstance *)Instance; + free(Vocoder); +} + +/*****************************************************************************/ + +LADSPA_Descriptor * g_psDescriptor = NULL; + +/*****************************************************************************/ + +/* _init() is called automatically when the plugin library is first + loaded. */ +void +_init() { + char ** pcPortNames; + LADSPA_PortDescriptor * piPortDescriptors; + LADSPA_PortRangeHint * psPortRangeHints; + int i; + + g_psDescriptor = (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor)); + + if (g_psDescriptor) { + g_psDescriptor->UniqueID = LADSPA_UNIQUE_ID; + g_psDescriptor->Label = strdup("vocoder-lmms"); + g_psDescriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE; + g_psDescriptor->Name = strdup("Vocoder for LMMS"); + g_psDescriptor->Maker = strdup("Achim Settelmeier (adapted to LADSPA by Josh Green, adapted to LMMS by Hexasoft)"); + g_psDescriptor->Copyright = strdup("GPL"); + g_psDescriptor->PortCount = PORT_COUNT; + piPortDescriptors = (LADSPA_PortDescriptor *)calloc(PORT_COUNT, + sizeof(LADSPA_PortDescriptor)); + g_psDescriptor->PortDescriptors + = (const LADSPA_PortDescriptor *)piPortDescriptors; + piPortDescriptors[PORT_FORMANT] + = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + piPortDescriptors[PORT_CARRIER] + = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO; + piPortDescriptors[PORT_OUTPUT] + = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + piPortDescriptors[PORT_OUTPUT2] + = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + piPortDescriptors[CTRL_BANDCOUNT] + = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + piPortDescriptors[CTRL_PAN] + = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + + pcPortNames = (char **)calloc(PORT_COUNT, sizeof(char *)); + g_psDescriptor->PortNames = (const char **)pcPortNames; + pcPortNames[PORT_FORMANT] = strdup("Formant-in"); + pcPortNames[PORT_CARRIER] = strdup("Carrier-in"); + pcPortNames[PORT_OUTPUT] = strdup("Output-out"); + pcPortNames[PORT_OUTPUT2] = strdup("Output2-out"); + pcPortNames[CTRL_BANDCOUNT] = strdup("Number of bands"); + pcPortNames[CTRL_PAN] = strdup("Left/Right"); + + psPortRangeHints = ((LADSPA_PortRangeHint *) + calloc(PORT_COUNT, sizeof(LADSPA_PortRangeHint))); + g_psDescriptor->PortRangeHints + = (const LADSPA_PortRangeHint *)psPortRangeHints; + psPortRangeHints[PORT_FORMANT].HintDescriptor = 0; + psPortRangeHints[PORT_CARRIER].HintDescriptor = 0; + psPortRangeHints[PORT_OUTPUT].HintDescriptor = 0; + psPortRangeHints[PORT_OUTPUT2].HintDescriptor = 0; + psPortRangeHints[CTRL_BANDCOUNT].HintDescriptor + = LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE + | LADSPA_HINT_INTEGER; + psPortRangeHints[CTRL_BANDCOUNT].LowerBound = 1; + psPortRangeHints[CTRL_BANDCOUNT].UpperBound = MAX_BANDS; + psPortRangeHints[CTRL_PAN].HintDescriptor + = LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE + | LADSPA_HINT_INTEGER; + psPortRangeHints[CTRL_PAN].LowerBound = -100; + psPortRangeHints[CTRL_PAN].UpperBound = +100; + + for (i=CTRL_BAND1LVL; i < CTRL_BAND1LVL + MAX_BANDS; i++) + { + piPortDescriptors[i] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL; + pcPortNames[i] = malloc (sizeof ("Band 99 Level")); + sprintf(pcPortNames[i], "Band %d Level", i - CTRL_BAND1LVL + 1); + psPortRangeHints[i].HintDescriptor + = LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE; + psPortRangeHints[i].LowerBound = 0; + psPortRangeHints[i].UpperBound = 1; + } + + g_psDescriptor->instantiate = instantiateVocoder; + g_psDescriptor->connect_port = connectPortToVocoder; + g_psDescriptor->activate = activateVocoder; + g_psDescriptor->run = runVocoder; + g_psDescriptor->run_adding = NULL; + g_psDescriptor->set_run_adding_gain = NULL; + g_psDescriptor->deactivate = NULL; + g_psDescriptor->cleanup = cleanupVocoder; + } +} + +/*****************************************************************************/ + +/* _fini() is called automatically when the library is unloaded. */ +void +_fini() { + long lIndex; + if (g_psDescriptor) { + free((char *)g_psDescriptor->Label); + free((char *)g_psDescriptor->Name); + free((char *)g_psDescriptor->Maker); + free((char *)g_psDescriptor->Copyright); + free((LADSPA_PortDescriptor *)g_psDescriptor->PortDescriptors); + for (lIndex = 0; lIndex < g_psDescriptor->PortCount; lIndex++) + free((char *)(g_psDescriptor->PortNames[lIndex])); + free((char **)g_psDescriptor->PortNames); + free((LADSPA_PortRangeHint *)g_psDescriptor->PortRangeHints); + free(g_psDescriptor); + } +} + +/*****************************************************************************/ + +/* Return a descriptor of the requested plugin type. Only one plugin + type is available in this library. */ +const LADSPA_Descriptor * +ladspa_descriptor(unsigned long Index) { + if (Index == 0) + return g_psDescriptor; + else + return NULL; +} + +/*****************************************************************************/ + +/* EOF */ diff --git a/plugins/midi_import/MidiImport.cpp b/plugins/midi_import/MidiImport.cpp index 585c2f5eba..0444ce51a9 100644 --- a/plugins/midi_import/MidiImport.cpp +++ b/plugins/midi_import/MidiImport.cpp @@ -38,6 +38,7 @@ #include "pattern.h" #include "Instrument.h" #include "MainWindow.h" +#include "MidiTime.h" #include "debug.h" #include "embed.h" #include "song.h" @@ -152,7 +153,7 @@ public: AutomationTrack * at; AutomationPattern * ap; - midiTime lastPos; + MidiTime lastPos; smfMidiCC & create( TrackContainer* tc ) { @@ -172,11 +173,11 @@ public: } - smfMidiCC & putValue( midiTime time, AutomatableModel * objModel, float value ) + smfMidiCC & putValue( MidiTime time, AutomatableModel * objModel, float value ) { if( !ap || time > lastPos + DefaultTicksPerTact ) { - midiTime pPos = midiTime( time.getTact(), 0 ); + MidiTime pPos = MidiTime( time.getTact(), 0 ); ap = dynamic_cast( at->createTCO(0) ); ap->movePosition( pPos ); @@ -186,7 +187,7 @@ public: lastPos = time; time = time - ap->startPosition(); ap->putValue( time, value, false ); - ap->changeLength( midiTime( time.getTact() + 1, 0 ) ); + ap->changeLength( MidiTime( time.getTact() + 1, 0 ) ); return *this; } @@ -212,7 +213,7 @@ public: Instrument * it_inst; bool isSF2; bool hasNotes; - midiTime lastEnd; + MidiTime lastEnd; smfMidiChannel * create( TrackContainer* tc ) { @@ -247,7 +248,7 @@ public: { if( !p || n.pos() > lastEnd + DefaultTicksPerTact ) { - midiTime pPos = midiTime(n.pos().getTact(), 0 ); + MidiTime pPos = MidiTime( n.pos().getTact(), 0 ); p = dynamic_cast( it->createTCO( 0 ) ); p->movePosition( pPos ); } diff --git a/plugins/midi_import/MidiImport.h b/plugins/midi_import/MidiImport.h index 47ad494864..66b839334f 100644 --- a/plugins/midi_import/MidiImport.h +++ b/plugins/midi_import/MidiImport.h @@ -29,7 +29,7 @@ #include #include -#include "midi.h" +#include "MidiEvent.h" #include "ImportFilter.h" @@ -117,8 +117,8 @@ private: } - typedef QVector > eventVector; - eventVector m_events; + typedef QVector > EventVector; + EventVector m_events; int m_timingDivision; } ; diff --git a/plugins/opl2/CMakeLists.txt b/plugins/opl2/CMakeLists.txt index 0b9bd32cd8..981ec53a36 100644 --- a/plugins/opl2/CMakeLists.txt +++ b/plugins/opl2/CMakeLists.txt @@ -1,3 +1,3 @@ INCLUDE(BuildPlugin) -BUILD_PLUGIN(OPL2 opl2instrument.cpp opl2instrument.h opl.h kemuopl.h adlibemu.c adlibemu.h fmopl.c fmopl.h temuopl.cpp temuopl.h MOCFILES opl2instrument.h EMBEDDED_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.png) \ No newline at end of file +BUILD_PLUGIN(OPL2 opl2instrument.cpp opl2instrument.h opl.h fmopl.c fmopl.h temuopl.cpp temuopl.h MOCFILES opl2instrument.h EMBEDDED_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.png) \ No newline at end of file diff --git a/plugins/opl2/COPYING.LESSER b/plugins/opl2/COPYING.LESSER new file mode 100644 index 0000000000..4362b49151 --- /dev/null +++ b/plugins/opl2/COPYING.LESSER @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/plugins/opl2/adlibemu.c b/plugins/opl2/adlibemu.c deleted file mode 100644 index 9aac3a6fcd..0000000000 --- a/plugins/opl2/adlibemu.c +++ /dev/null @@ -1,608 +0,0 @@ -/* - * ADLIBEMU.C - * Copyright (C) 1998-2001 Ken Silverman - * Ken Silverman's official web site: "http://www.advsys.net/ken" - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* -This file is a digital Adlib emulator for OPL2 and possibly OPL3 - -Features that could be added in a future version: -- Amplitude and Frequency Vibrato Bits (not hard, but a big speed hit) -- Global Keyboard Split Number Bit (need to research this one some more) -- 2nd Adlib chip for OPL3 (simply need to make my cell array bigger) -- Advanced connection modes of OPL3 (Just need to add more "docell" cases) -- L/R Stereo bits of OPL3 (Need adlibgetsample to return stereo) - -Features that aren't worth supporting: -- Anything related to adlib timers&interrupts (Sorry - I always used IRQ0) -- Composite sine wave mode (CSM) (Supported only on ancient cards) - -I'm not sure about a few things in my code: -- Attack curve. What function is this anyway? I chose to use an order-3 - polynomial to approximate but this doesn't seem right. -- Attack/Decay/Release constants - my constants may not be exact -- What should ADJUSTSPEED be? -- Haven't verified that Global Keyboard Split Number Bit works yet -- Some of the drums don't always sound right. It's pretty hard to guess - the exact waveform of drums when you look at random data which is - slightly randomized due to digital ADC recording. -- Adlib seems to have a lot more treble than my emulator does. I'm not - sure if this is simply unfixable due to the sound blaster's different - filtering on FM and digital playback or if it's a serious bug in my - code. -*/ - -#include -#include - -#if !defined(max) && !defined(__cplusplus) -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#if !defined(min) && !defined(__cplusplus) -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#define PI 3.141592653589793 -#define MAXCELLS 18 -#define WAVPREC 2048 - -static float AMPSCALE=(8192.0); -#define FRQSCALE (49716/512.0) - -//Constants for Ken's Awe32, on a PII-266 (Ken says: Use these for KSM's!) -#define MODFACTOR 4.0 //How much of modulator cell goes into carrier -#define MFBFACTOR 1.0 //How much feedback goes back into modulator -#define ADJUSTSPEED 0.75 //0<=x<=1 Simulate finite rate of change of state - -//Constants for Ken's Awe64G, on a P-133 -//#define MODFACTOR 4.25 //How much of modulator cell goes into carrier -//#define MFBFACTOR 0.5 //How much feedback goes back into modulator -//#define ADJUSTSPEED 0.85 //0<=x<=1 Simulate finite rate of change of state - -typedef struct -{ - float val, t, tinc, vol, sustain, amp, mfb; - float a0, a1, a2, a3, decaymul, releasemul; - short *waveform; - long wavemask; - void (*cellfunc)(void *, float); - unsigned char flags, dum0, dum1, dum2; -} celltype; - -static long numspeakers, bytespersample; -static float recipsamp; -static celltype cell[MAXCELLS]; -static signed short wavtable[WAVPREC*3]; -static float kslmul[4] = {0.0,0.5,0.25,1.0}; -static float frqmul[16] = {.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15}, nfrqmul[16]; -static unsigned char adlibreg[256], ksl[8][16]; -static unsigned char modulatorbase[9] = {0,1,2,8,9,10,16,17,18}; -static unsigned char odrumstat = 0; -static unsigned char base2cell[22] = {0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8}; - -float lvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on left speaker -float rvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on right speaker -long lplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on left speaker -long rplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on right speaker - -long nlvol[9], nrvol[9]; -long nlplc[9], nrplc[9]; -long rend = 0; -#define FIFOSIZ 256 -static float *rptr[9], *nrptr[9]; -static float rbuf[9][FIFOSIZ*2]; -static float snd[FIFOSIZ*2]; - -#ifndef USING_ASM -#define _inline -#endif - -#ifdef USING_ASM -static _inline void ftol (float f, long *a) -{ - _asm - { - mov eax, a - fld f - fistp dword ptr [eax] - } -} -#else -static void ftol(float f, long *a) { - *a=f; -} -#endif - -#define ctc ((celltype *)c) //A rare attempt to make code easier to read! -void docell4 (void *c, float modulator) { } -void docell3 (void *c, float modulator) -{ - long i; - - ftol(ctc->t+modulator,&i); - ctc->t += ctc->tinc; - ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED; -} -void docell2 (void *c, float modulator) -{ - long i; - - ftol(ctc->t+modulator,&i); - - void *amp_void = &ctc->amp; - long *amp_long = (long *)amp_void; - if (*amp_long <= 0x37800000) - { - ctc->amp = 0; - ctc->cellfunc = docell4; - } - ctc->amp *= ctc->releasemul; - - ctc->t += ctc->tinc; - ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED; -} -void docell1 (void *c, float modulator) -{ - long i; - - ftol(ctc->t+modulator,&i); - - void *amp_void = &ctc->amp; - long *amp_long = (long *)amp_void; - void *sustain_void = &ctc->sustain; - long *sustain_long = (long *)sustain_void; - if (*amp_long <= *sustain_long) - { - if (ctc->flags&32) - { - ctc->amp = ctc->sustain; - ctc->cellfunc = docell3; - } - else - ctc->cellfunc = docell2; - } - else - ctc->amp *= ctc->decaymul; - - ctc->t += ctc->tinc; - ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED; -} -void docell0 (void *c, float modulator) -{ - long i; - - ftol(ctc->t+modulator,&i); - - ctc->amp = ((ctc->a3*ctc->amp + ctc->a2)*ctc->amp + ctc->a1)*ctc->amp + ctc->a0; - void *amp_void = &ctc->amp; - long *amp_long = (long *)amp_void; - if (*amp_long > 0x3f800000) - { - ctc->amp = 1; - ctc->cellfunc = docell1; - } - - ctc->t += ctc->tinc; - ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED; -} - - -static long waveform[8] = {WAVPREC,WAVPREC>>1,WAVPREC,(WAVPREC*3)>>2,0,0,(WAVPREC*5)>>2,WAVPREC<<1}; -static long wavemask[8] = {WAVPREC-1,WAVPREC-1,(WAVPREC>>1)-1,(WAVPREC>>1)-1,WAVPREC-1,((WAVPREC*3)>>2)-1,WAVPREC>>1,WAVPREC-1}; -static long wavestart[8] = {0,WAVPREC>>1,0,WAVPREC>>2,0,0,0,WAVPREC>>3}; -static float attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744}; -static float decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608}; -void cellon (long i, long j, celltype *c, unsigned char iscarrier) -{ - long frn, oct, toff; - float f; - - frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0]; - oct = ((((long)adlibreg[i+0xb0])>>2)&7); - toff = (oct<<1) + ((frn>>9)&((frn>>8)|(((adlibreg[8]>>6)&1)^1))); - if (!(adlibreg[j+0x20]&16)) toff >>= 2; - - f = pow(2.0,(adlibreg[j+0x60]>>4)+(toff>>2)-1)*attackconst[toff&3]*recipsamp; - c->a0 = .0377*f; c->a1 = 10.73*f+1; c->a2 = -17.57*f; c->a3 = 7.42*f; - f = -7.4493*decrelconst[toff&3]*recipsamp; - c->decaymul = pow(2.0,f*pow(2.0,(adlibreg[j+0x60]&15)+(toff>>2))); - c->releasemul = pow(2.0,f*pow(2.0,(adlibreg[j+0x80]&15)+(toff>>2))); - c->wavemask = wavemask[adlibreg[j+0xe0]&7]; - c->waveform = &wavtable[waveform[adlibreg[j+0xe0]&7]]; - if (!(adlibreg[1]&0x20)) c->waveform = &wavtable[WAVPREC]; - c->t = wavestart[adlibreg[j+0xe0]&7]; - c->flags = adlibreg[j+0x20]; - c->cellfunc = docell0; - c->tinc = (float)(frn<vol = pow(2.0,((float)(adlibreg[j+0x40]&63) + - (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14); - c->sustain = pow(2.0,(float)(adlibreg[j+0x80]>>4) * -.5); - if (!iscarrier) c->amp = 0; - c->mfb = pow(2.0,((adlibreg[i+0xc0]>>1)&7)+5)*(WAVPREC/2048.0)*MFBFACTOR; - if (!(adlibreg[i+0xc0]&14)) c->mfb = 0; - c->val = 0; -} - -//This function (and bug fix) written by Chris Moeller -void cellfreq (signed long i, signed long j, celltype *c) -{ - long frn, oct; - - frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0]; - oct = ((((long)adlibreg[i+0xb0])>>2)&7); - - c->tinc = (float)(frn<vol = pow(2.0,((float)(adlibreg[j+0x40]&63) + - (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14); -} - -static long initfirstime = 0; -void adlibinit (long dasamplerate, long danumspeakers, long dabytespersample) -{ - long i, j, frn, oct; - - memset((void *)adlibreg,0,sizeof(adlibreg)); - memset((void *)cell,0,sizeof(celltype)*MAXCELLS); - memset((void *)rbuf,0,sizeof(rbuf)); - rend = 0; odrumstat = 0; - - for(i=0;i=0;i--) nfrqmul[i] = frqmul[i]*recipsamp*FRQSCALE*(WAVPREC/2048.0); - - if (!initfirstime) - { - initfirstime = 1; - - for(i=0;i<(WAVPREC>>1);i++) - { - wavtable[i] = - wavtable[(i<<1) +WAVPREC] = (signed short)(16384*sin((float)((i<<1) )*PI*2/WAVPREC)); - wavtable[(i<<1)+1+WAVPREC] = (signed short)(16384*sin((float)((i<<1)+1)*PI*2/WAVPREC)); - } - for(i=0;i<(WAVPREC>>3);i++) - { - wavtable[i+(WAVPREC<<1)] = wavtable[i+(WAVPREC>>3)]-16384; - wavtable[i+((WAVPREC*17)>>3)] = wavtable[i+(WAVPREC>>2)]+16384; - } - - //[table in book]*8/3 - ksl[7][0] = 0; ksl[7][1] = 24; ksl[7][2] = 32; ksl[7][3] = 37; - ksl[7][4] = 40; ksl[7][5] = 43; ksl[7][6] = 45; ksl[7][7] = 47; - ksl[7][8] = 48; for(i=9;i<16;i++) ksl[7][i] = i+41; - for(j=6;j>=0;j--) - for(i=0;i<16;i++) - { - oct = (long)ksl[j+1][i]-8; if (oct < 0) oct = 0; - ksl[j][i] = (unsigned char)oct; - } - } - else - { - for(i=0;i<9;i++) - { - frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0]; - oct = ((((long)adlibreg[i+0xb0])>>2)&7); - cell[i].tinc = (float)(frn< (odrumstat&16)) //BassDrum - { - cellon(6,16,&cell[6],0); - cellon(6,19,&cell[15],1); - cell[15].vol *= 2; - } - if ((v&8) > (odrumstat&8)) //Snare - { - cellon(16,20,&cell[16],0); - cell[16].tinc *= 2*(nfrqmul[adlibreg[17+0x20]&15] / nfrqmul[adlibreg[20+0x20]&15]); - if (((adlibreg[20+0xe0]&7) >= 3) && ((adlibreg[20+0xe0]&7) <= 5)) cell[16].vol = 0; - cell[16].vol *= 2; - } - if ((v&4) > (odrumstat&4)) //TomTom - { - cellon(8,18,&cell[8],0); - cell[8].vol *= 2; - } - if ((v&2) > (odrumstat&2)) //Cymbal - { - cellon(17,21,&cell[17],0); - - cell[17].wavemask = wavemask[5]; - cell[17].waveform = &wavtable[waveform[5]]; - cell[17].tinc *= 16; cell[17].vol *= 2; - - //cell[17].waveform = &wavtable[WAVPREC]; cell[17].wavemask = 0; - //if (((adlibreg[21+0xe0]&7) == 0) || ((adlibreg[21+0xe0]&7) == 6)) - // cell[17].waveform = &wavtable[(WAVPREC*7)>>2]; - //if (((adlibreg[21+0xe0]&7) == 2) || ((adlibreg[21+0xe0]&7) == 3)) - // cell[17].waveform = &wavtable[(WAVPREC*5)>>2]; - } - if ((v&1) > (odrumstat&1)) //Hihat - { - cellon(7,17,&cell[7],0); - if (((adlibreg[17+0xe0]&7) == 1) || ((adlibreg[17+0xe0]&7) == 4) || - ((adlibreg[17+0xe0]&7) == 5) || ((adlibreg[17+0xe0]&7) == 7)) cell[7].vol = 0; - if ((adlibreg[17+0xe0]&7) == 6) { cell[7].wavemask = 0; cell[7].waveform = &wavtable[(WAVPREC*7)>>2]; } - } - - odrumstat = v; - } - else if (((unsigned)(i-0x40) < (unsigned)22) && ((i&7) < 6)) - { - if ((i&7) < 3) // Modulator - cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]]); - else // Carrier - cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]+9]); - } - else if ((unsigned)(i-0xa0) < (unsigned)9) - { - cellfreq(i-0xa0,modulatorbase[i-0xa0],&cell[i-0xa0]); - cellfreq(i-0xa0,modulatorbase[i-0xa0]+3,&cell[i-0xa0+9]); - } - else if ((unsigned)(i-0xb0) < (unsigned)9) - { - if ((v&32) > (tmp&32)) - { - cellon(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0],0); - cellon(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9],1); - } - else if ((v&32) < (tmp&32)) - cell[i-0xb0].cellfunc = cell[i-0xb0+9].cellfunc = docell2; - cellfreq(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0]); - cellfreq(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9]); - } - - //outdata(i,v); -} - -#ifdef USING_ASM -static long fpuasm; -static float fakeadd = 8388608.0+128.0; -static _inline void clipit8 (float f, long a) -{ - _asm - { - mov edi, a - fld dword ptr f - fadd dword ptr fakeadd - fstp dword ptr fpuasm - mov eax, fpuasm - test eax, 0x007fff00 - jz short skipit - shr eax, 16 - xor eax, -1 - skipit: mov byte ptr [edi], al - } -} - -static _inline void clipit16 (float f, long a) -{ - _asm - { - mov eax, a - fld dword ptr f - fist word ptr [eax] - cmp word ptr [eax], 0x8000 - jne short skipit2 - fst dword ptr [fpuasm] - cmp fpuasm, 0x80000000 - sbb word ptr [eax], 0 - skipit2: fstp st - } -} -#else -static void clipit8(float f,unsigned char *a) { - f/=256.0; - f+=128.0; - if (f>254.5) *a=255; - else if (f<0.5) *a=0; - else *a=f; -} - -static void clipit16(float f,short *a) { - if (f>32766.5) *a=32767; - else if (f<-32767.5) *a=-32768; - else *a=f; -} -#endif - -void adlibsetvolume(int i) { - AMPSCALE=i; -} - -void adlibgetsample (unsigned char *sndptr, long numbytes) -{ - long i, j, k=0, ns, endsamples, rptrs, numsamples; - celltype *cptr; - float f; - short *sndptr2=(short *)sndptr; - - numsamples = (numbytes>>(numspeakers+bytespersample-2)); - - if (bytespersample == 1) f = AMPSCALE/256.0; else f = AMPSCALE; - if (numspeakers == 1) - { - nlvol[0] = lvol[0]*f; - for(i=0;i<9;i++) rptr[i] = &rbuf[0][0]; - rptrs = 1; - } - else - { - rptrs = 0; - for(i=0;i<9;i++) - { - if ((!i) || (lvol[i] != lvol[i-1]) || (rvol[i] != rvol[i-1]) || - (lplc[i] != lplc[i-1]) || (rplc[i] != rplc[i-1])) - { - nlvol[rptrs] = lvol[i]*f; - nrvol[rptrs] = rvol[i]*f; - nlplc[rptrs] = rend-min(max(lplc[i],0),FIFOSIZ); - nrplc[rptrs] = rend-min(max(rplc[i],0),FIFOSIZ); - rptrs++; - } - rptr[i] = &rbuf[rptrs-1][0]; - } - } - - - //CPU time used to be somewhat less when emulator was only mono! - // Because of no delay fifos! - - for(ns=0;ns>1)-1)); //Snare - (cell[7].cellfunc)((void *)&cell[7],k&(WAVPREC-1)); //Hihat - (cell[17].cellfunc)((void *)&cell[17],k&((WAVPREC>>3)-1)); //Cymbal - (cell[8].cellfunc)((void *)&cell[8],0.0); //TomTom - nrptr[7][i] += cell[7].val + cell[16].val; - nrptr[8][i] += cell[8].val + cell[17].val; - } - } - } - for(j=9-1;j>=0;j--) - { - if ((adlibreg[0xbd]&0x20) && (j >= 6) && (j < 9)) continue; - - cptr = &cell[j]; k = j; - if (adlibreg[0xc0+k]&1) - { - if ((cptr[9].cellfunc == docell4) && (cptr->cellfunc == docell4)) continue; - for(i=0;icellfunc)((void *)cptr,cptr->val*cptr->mfb); - (cptr->cellfunc)((void *)&cptr[9],0); - nrptr[j][i] += cptr[9].val + cptr->val; - } - } - else - { - if (cptr[9].cellfunc == docell4) continue; - for(i=0;icellfunc)((void *)cptr,cptr->val*cptr->mfb); - (cptr[9].cellfunc)((void *)&cptr[9],cptr->val*WAVPREC*MODFACTOR); - nrptr[j][i] += cptr[9].val; - } - } - } - - if (numspeakers == 1) - { - if (bytespersample == 1) - { - for(i=endsamples-1;i>=0;i--) - clipit8(nrptr[0][i]*nlvol[0],sndptr+1); - } - else - { - for(i=endsamples-1;i>=0;i--) - clipit16(nrptr[0][i]*nlvol[0],sndptr2+i); - } - } - else - { - memset((void *)snd,0,endsamples*sizeof(float)*2); - for(j=0;j=0;i--) - clipit8(snd[i],sndptr+i); - } - else - { - for(i=(endsamples<<1)-1;i>=0;i--) - clipit16(snd[i],sndptr2+i); - } - } - - sndptr = sndptr+(numspeakers*endsamples); - sndptr2 = sndptr2+(numspeakers*endsamples); - rend = ((rend+endsamples)&(FIFOSIZ*2-1)); - } -} diff --git a/plugins/opl2/adlibemu.h b/plugins/opl2/adlibemu.h deleted file mode 100644 index 8600d787d8..0000000000 --- a/plugins/opl2/adlibemu.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * ADLIBEMU.H - * Copyright (C) 1998-2001 Ken Silverman - * Ken Silverman's official web site: "http://www.advsys.net/ken" - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -void adlibinit(long dasamplerate,long danumspeakers,long dabytespersample); -void adlib0(long i,long v); -void adlibgetsample(void *sndptr,long numbytes); -void adlibsetvolume(int i); -void randoinsts(); -extern float lvol[9],rvol[9],lplc[9],rplc[9]; diff --git a/plugins/opl2/fmopl.c b/plugins/opl2/fmopl.c index 2b0e82b0cc..db5180189c 100644 --- a/plugins/opl2/fmopl.c +++ b/plugins/opl2/fmopl.c @@ -596,7 +596,7 @@ static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE ) OPL->AR_TABLE[i] = rate / ARRATE; OPL->DR_TABLE[i] = rate / DRRATE; } - for (i = 60;i < 76;i++) + for (i = 60;i < 75;i++) { OPL->AR_TABLE[i] = EG_AED-1; OPL->DR_TABLE[i] = OPL->DR_TABLE[60]; diff --git a/plugins/opl2/kemuopl.h b/plugins/opl2/kemuopl.h deleted file mode 100644 index d2ca6e288f..0000000000 --- a/plugins/opl2/kemuopl.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Adplug - Replayer for many OPL2/OPL3 audio file formats. - * Copyright (C) 1999 - 2005 Simon Peter, , et al. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * kemuopl.h - Emulated OPL using Ken Silverman's emulator, by Simon Peter - * - */ - -#ifndef H_ADPLUG_KEMUOPL -#define H_ADPLUG_KEMUOPL - -#include "opl.h" -extern "C" { -#include "adlibemu.h" -} - -class CKemuopl: public Copl -{ -public: - CKemuopl(int rate, bool bit16, bool usestereo) - : use16bit(bit16), stereo(usestereo) - { - adlibinit(rate, usestereo ? 2 : 1, bit16 ? 2 : 1); - currType = TYPE_OPL2; - }; - - void update(short *buf, int samples) - { - if(use16bit) samples *= 2; - if(stereo) samples *= 2; - adlibgetsample(buf, samples); - } - - // template methods - void write(int reg, int val) - { - if(currChip == 0) - adlib0(reg, val); - }; - - void init() {}; - -private: - bool use16bit,stereo; -}; - -#endif diff --git a/plugins/opl2/logo.png b/plugins/opl2/logo.png index a5b8256e41..fab0301603 100644 Binary files a/plugins/opl2/logo.png and b/plugins/opl2/logo.png differ diff --git a/plugins/opl2/opl2instrument.cpp b/plugins/opl2/opl2instrument.cpp index 34fd186df6..5f41b6454f 100644 --- a/plugins/opl2/opl2instrument.cpp +++ b/plugins/opl2/opl2instrument.cpp @@ -1,7 +1,7 @@ /* * OPL2 FM synth * - * Copyright (c) 2013 Raine M. Ekman + * Copyright (c) 2014 Raine M. Ekman * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -23,10 +23,10 @@ */ // TODO: -// - Pitch bend -// - Velocity (and aftertouch) sensitivity -// - in FM mode: OP2 level, add mode: OP1 and OP2 levels +// - Better voice allocation: long releases get cut short :( // - .sbi (or similar) file loading into models +// - RT safety = get rid of mutex = make emulator code thread-safe + // - Extras: // - double release: first release is in effect until noteoff (heard if percussive sound), // second is switched in just before key bit cleared (is this useful???) @@ -53,7 +53,6 @@ #include "opl.h" #include "temuopl.h" -#include "kemuopl.h" #include "embed.cpp" #include "math.h" @@ -92,6 +91,9 @@ Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data ) // the emulator code isn't really ready for threads QMutex opl2instrument::emulatorMutex; +// Weird ordering of voice parameters +const unsigned int adlib_opadd[9] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; + opl2instrument::opl2instrument( InstrumentTrack * _instrument_track ) : Instrument( _instrument_track, &OPL2_plugin_descriptor ), m_patchModel( 0, 0, 127, this, tr( "Patch" ) ), @@ -139,28 +141,38 @@ opl2instrument::opl2instrument( InstrumentTrack * _instrument_track ) : InstrumentPlayHandle * iph = new InstrumentPlayHandle( this ); engine::mixer()->addPlayHandle( iph ); + // Voices are laid out in a funny way... + // adlib_opadd = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; + // Create an emulator - samplerate, 16 bit, mono - // CTemuopl is the better one, CKemuopl kinda sucks (some sounds silent, pitch goes flat after a while) emulatorMutex.lock(); - // theEmulator = new CKemuopl(engine::mixer()->processingSampleRate(), true, false); theEmulator = new CTemuopl(engine::mixer()->processingSampleRate(), true, false); theEmulator->init(); // Enable waveform selection theEmulator->write(0x01,0x20); emulatorMutex.unlock(); + //Initialize voice values + voiceNote[0] = 0; + voiceLRU[0] = 0; + for(int i=1; i<9; ++i) { + voiceNote[i] = OPL2_VOICE_FREE; + voiceLRU[i] = i; + } + updatePatch(); // Can the buffer size change suddenly? I bet that would break lots of stuff frameCount = engine::mixer()->framesPerPeriod(); renderbuffer = new short[frameCount]; - // Some kind of sane default + // Some kind of sane defaults + pitchbend = 0; + pitchBendRange = 100; + RPNcoarse = RPNfine = 255; + tuneEqual(69, 440); - for(int i=1; i<9; ++i) { - voiceNote[i] = OPL2_VOICE_FREE; - } connect( engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( reloadEmulator() ) ); // Connect knobs @@ -207,8 +219,15 @@ opl2instrument::opl2instrument( InstrumentTrack * _instrument_track ) : MOD_CON( trem_depth_mdl ); } +opl2instrument::~opl2instrument() { + delete theEmulator; + engine::mixer()->removePlayHandles( instrumentTrack() ); + delete [] renderbuffer; +} + // Samplerate changes when choosing oversampling, so this is more or less mandatory void opl2instrument::reloadEmulator() { + delete theEmulator; emulatorMutex.lock(); theEmulator = new CTemuopl(engine::mixer()->processingSampleRate(), true, false); theEmulator->init(); @@ -216,50 +235,141 @@ void opl2instrument::reloadEmulator() { emulatorMutex.unlock(); for(int i=1; i<9; ++i) { voiceNote[i] = OPL2_VOICE_FREE; + voiceLRU[i] = i; } updatePatch(); } -bool opl2instrument::handleMidiEvent( const midiEvent & _me, - const midiTime & _time ) +// This shall only be called from code protected by the holy Mutex! +void opl2instrument::setVoiceVelocity(int voice, int vel) { + int vel_adjusted; + // Velocity calculation, some kind of approximation + // Only calculate for operator 1 if in adding mode, don't want to change timbre + if( fm_mdl.value() == false ) { + vel_adjusted = 63 - ( op1_lvl_mdl.value() * vel/127.0) ; + } else { + vel_adjusted = 63 - op1_lvl_mdl.value(); + } + theEmulator->write(0x40+adlib_opadd[voice], + ( (int)op1_scale_mdl.value() & 0x03 << 6) + + ( vel_adjusted & 0x3f ) ); + + + vel_adjusted = 63 - ( op2_lvl_mdl.value() * vel/127.0 ); + // vel_adjusted = 63 - op2_lvl_mdl.value(); + theEmulator->write(0x43+adlib_opadd[voice], + ( (int)op2_scale_mdl.value() & 0x03 << 6) + + ( vel_adjusted & 0x3f ) ); +} + +// Pop least recently used voice - why does it sometimes lose a voice (mostly 0)? +int opl2instrument::popVoice() { + int tmp = voiceLRU[0]; + for( int i=0; i<8; ++i) { + voiceLRU[i] = voiceLRU[i+1]; + } + voiceLRU[8] = OPL2_NO_VOICE; + return tmp; +} + +int opl2instrument::pushVoice(int v) { + int i; + for(i=8; i>0; --i) { + if( voiceLRU[i-1] != OPL2_NO_VOICE ) { + break; + } + } + voiceLRU[i] = v; + return i; +} + +bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time ) { emulatorMutex.lock(); - // Real dummy version... Should at least add: - // - smarter voice allocation: - // - reuse same note, now we have round robin-ish - // - what to do when voices run out and so on... - // - mono mode - // - int key; - static int lastvoice=0; - if( _me.m_type == MidiNoteOn ) { - // to get us in line with MIDI - key = _me.key() +12; - for(int i=lastvoice+1; i!=lastvoice; ++i,i%=9) { - if( voiceNote[i] == OPL2_VOICE_FREE ) { - theEmulator->write(0xA0+i, fnums[key] & 0xff); - theEmulator->write(0xB0+i, 32 + ((fnums[key] & 0x1f00) >> 8) ); - // printf("%d: %d %d\n", key, (fnums[key] & 0x1c00) >> 10, fnums[key] & 0x3ff); - voiceNote[i] = key; - // printf("Voice %d on\n",i); - lastvoice=i; - break; + int key, vel, voice, tmp_pb; + + switch(event.type()) { + case MidiNoteOn: + // to get us in line with MIDI(?) + key = event.key() +12; + vel = event.velocity(); + + voice = popVoice(); + if( voice != OPL2_NO_VOICE ) { + // Turn voice on, NB! the frequencies are straight by voice number, + // not by the adlib_opadd table! + theEmulator->write(0xA0+voice, fnums[key] & 0xff); + theEmulator->write(0xB0+voice, 32 + ((fnums[key] & 0x1f00) >> 8) ); + setVoiceVelocity(voice, vel); + voiceNote[voice] = key; + velocities[key] = vel; + } + break; + case MidiNoteOff: + key = event.key() +12; + for(voice=0; voice<9; ++voice) { + if( voiceNote[voice] == key ) { + theEmulator->write(0xA0+voice, fnums[key] & 0xff); + theEmulator->write(0xB0+voice, (fnums[key] & 0x1f00) >> 8 ); + voiceNote[voice] = OPL2_VOICE_FREE; + pushVoice(voice); + } + } + velocities[key] = 0; + break; + case MidiKeyPressure: + key = event.key() +12; + vel = event.velocity(); + if( velocities[key] != 0) { + velocities[key] = vel; + } + for(voice=0; voice<9; ++voice) { + if(voiceNote[voice] == key) { + setVoiceVelocity(voice, vel); } } - } else if( _me.m_type == MidiNoteOff ) { - key = _me.key() +12; - for(int i=0; i<9; ++i) { - if( voiceNote[i] == key ) { - theEmulator->write(0xA0+i, fnums[key] & 0xff); - theEmulator->write(0xB0+i, (fnums[key] & 0x1f00) >> 8 ); - voiceNote[i] = OPL2_VOICE_FREE; - } + break; + case MidiPitchBend: + // Update fnumber table + // Pitchbend should be in the range 0...16383 but the new range knob gets it wrong. + // tmp_pb = (2*BEND_CENTS)*((float)event.m_data.m_param[0]/16383)-BEND_CENTS; + + // Something like 100 cents = 8192, but offset by 8192 so the +/-100 cents range goes from 0...16383? + tmp_pb = ( event.pitchBend()-8192 ) * pitchBendRange / 8192; + + if( tmp_pb != pitchbend ) { + pitchbend = tmp_pb; + tuneEqual(69, 440.0); } - } else { - printf("Midi event type %d\n",_me.m_type); - // 224 - pitch wheel - // 160 - aftertouch? - } + // Update pitch of sounding notes + for( int v=0; v<9; ++v ) { + if( voiceNote[v] != OPL2_VOICE_FREE ) { + theEmulator->write(0xA0+v, fnums[voiceNote[v] ] & 0xff); + theEmulator->write(0xB0+v, 32 + ((fnums[voiceNote[v]] & 0x1f00) >> 8) ); + } + } + break; + case MidiControlChange: + switch (event.controllerNumber()) { + case MidiControllerRegisteredParameterNumberLSB: + RPNfine = event.controllerValue(); + break; + case MidiControllerRegisteredParameterNumberMSB: + RPNcoarse = event.controllerValue(); + break; + case MidiControllerDataEntry: + if( (RPNcoarse << 8) + RPNfine == MidiPitchBendSensitivityRPN) { + pitchBendRange = event.controllerValue() * 100; + } + break; + default: + printf("Midi CC %02x %02x\n", event.controllerNumber(), event.controllerValue() ); + break; + } + break; + default: + printf("Midi event type %d\n",event.type()); + } emulatorMutex.unlock(); return true; } @@ -332,7 +442,6 @@ void opl2instrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) void opl2instrument::loadSettings( const QDomElement & _this ) { - printf("loadSettings!\n"); op1_a_mdl.loadSettings( _this, "op1_a" ); op1_d_mdl.loadSettings( _this, "op1_d" ); op1_s_mdl.loadSettings( _this, "op1_s" ); @@ -366,19 +475,14 @@ void opl2instrument::loadSettings( const QDomElement & _this ) } -// Load a preset in binary form +// Load a patch into the emulator void opl2instrument::loadPatch(unsigned char inst[14]) { - const unsigned int adlib_opadd[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; - // Set all voices - printf("%02x %02x %02x %02x %02x ",inst[0],inst[1],inst[2],inst[3],inst[4]); - printf("%02x %02x %02x %02x %02x %02x\n",inst[5],inst[6],inst[7],inst[8],inst[9],inst[10]); - emulatorMutex.lock(); for(int v=0; v<9; ++v) { theEmulator->write(0x20+adlib_opadd[v],inst[0]); // op1 AM/VIB/EG/KSR/Multiplier theEmulator->write(0x23+adlib_opadd[v],inst[1]); // op2 - theEmulator->write(0x40+adlib_opadd[v],inst[2]); // op1 KSL/Output Level - theEmulator->write(0x43+adlib_opadd[v],inst[3]); // op2 + // theEmulator->write(0x40+adlib_opadd[v],inst[2]); // op1 KSL/Output Level - these are handled by noteon/aftertouch code + // theEmulator->write(0x43+adlib_opadd[v],inst[3]); // op2 theEmulator->write(0x60+adlib_opadd[v],inst[4]); // op1 A/D theEmulator->write(0x63+adlib_opadd[v],inst[5]); // op2 theEmulator->write(0x80+adlib_opadd[v],inst[6]); // op1 S/R @@ -391,10 +495,10 @@ void opl2instrument::loadPatch(unsigned char inst[14]) { } void opl2instrument::tuneEqual(int center, float Hz) { + float tmp; for(int n=0; n<128; ++n) { - float tmp = Hz*pow(2, (n-center)/12.0); + tmp = Hz*pow( 2, ( n - center ) / 12.0 + pitchbend / 1200.0 ); fnums[n] = Hz2fnum( tmp ); - //printf("%d: %d %d %f\n", n, (fnums[n] & 0x1c00) >> 10, fnums[n] & 0x3ff,tmp); } } @@ -412,7 +516,6 @@ int opl2instrument::Hz2fnum(float Hz) { // Load one of the default patches void opl2instrument::loadGMPatch() { unsigned char *inst = midi_fm_instruments[m_patchModel.value()]; - // printf("loadGMPatch: %d ", m_patchModel.value()); loadPatch(inst); } @@ -423,7 +526,6 @@ void opl2instrument::loadGMPatch() { // Update patch from the models to the chip emulation void opl2instrument::updatePatch() { - printf("updatePatch()\n"); unsigned char *inst = midi_fm_instruments[0]; inst[0] = ( op1_trem_mdl.value() ? 128 : 0 ) + ( op1_vib_mdl.value() ? 64 : 0 ) + @@ -456,10 +558,16 @@ void opl2instrument::updatePatch() { inst[12] = 0; inst[13] = 0; - // Not part of the patch per se + // Not part of the per-voice patch info theEmulator->write(0xBD, (trem_depth_mdl.value() ? 128 : 0 ) + (vib_depth_mdl.value() ? 64 : 0 )); + // have to do this, as the level knobs might've changed + for( int voice = 0; voice < 9 ; ++voice) { + if(voiceNote[voice]!=OPL2_VOICE_FREE) { + setVoiceVelocity(voice, velocities[voiceNote[voice]] ); + } + } loadPatch(inst); } @@ -552,9 +660,9 @@ opl2instrumentView::opl2instrumentView( Instrument * _instrument, pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); setPalette( pal ); - - - +} +opl2instrumentView::~opl2instrumentView() { + // Nobody else seems to delete their knobs and buttons? } void opl2instrumentView::modelChanged() @@ -604,4 +712,5 @@ void opl2instrumentView::modelChanged() } + #include "moc_opl2instrument.cxx" diff --git a/plugins/opl2/opl2instrument.h b/plugins/opl2/opl2instrument.h index 6933d7479f..9f47a0cfea 100644 --- a/plugins/opl2/opl2instrument.h +++ b/plugins/opl2/opl2instrument.h @@ -34,19 +34,23 @@ #include "pixmap_button.h" #define OPL2_VOICE_FREE 255 +#define OPL2_NO_VOICE 255 +// The "normal" range for LMMS pitchbends +#define DEFAULT_BEND_CENTS 100 class opl2instrument : public Instrument { Q_OBJECT public: opl2instrument( InstrumentTrack * _instrument_track ); + virtual ~opl2instrument(); + virtual QString nodeName() const; virtual PluginView * instantiateView( QWidget * _parent ); inline virtual bool isMidiBased() const { return true; } - virtual bool handleMidiEvent( const midiEvent & _me, - const midiTime & _time ); + virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time ); virtual void play( sampleFrame * _working_buffer ); void saveSettings( QDomDocument & _doc, QDomElement & _this ); @@ -107,20 +111,35 @@ private: fpp_t frameCount; short *renderbuffer; int voiceNote[9]; - int heldNotes[128]; + // Least recently used voices + int voiceLRU[9]; + // 0 - no note, >0 - note on velocity + int velocities[128]; // These include both octave and Fnumber int fnums[128]; + // in cents, range defaults to +/-100 cents (should this be changeable?) + int pitchbend; + int pitchBendRange; + + int popVoice(); + int pushVoice(int v); int Hz2fnum(float Hz); static QMutex emulatorMutex; + void setVoiceVelocity(int voice, int vel); + + // Pitch bend range comes through RPNs. + int RPNcoarse, RPNfine; }; + class opl2instrumentView : public InstrumentView { Q_OBJECT public: opl2instrumentView( Instrument * _instrument, QWidget * _parent ); + virtual ~opl2instrumentView(); lcdSpinBox *m_patch; void modelChanged(); diff --git a/plugins/papu/gb_apu/Gb_Apu.h b/plugins/papu/gb_apu/Gb_Apu.h index e2f940b94e..e41bdc2c2e 100644 --- a/plugins/papu/gb_apu/Gb_Apu.h +++ b/plugins/papu/gb_apu/Gb_Apu.h @@ -6,8 +6,8 @@ #ifndef GB_APU_H #define GB_APU_H -typedef long gb_time_t; // clock cycle count -typedef unsigned gb_addr_t; // 16-bit address +typedef int gb_time_t; // clock cycle count +typedef int gb_addr_t; // 16-bit address #include "Gb_Oscs.h" diff --git a/plugins/peak_controller_effect/artwork.png b/plugins/peak_controller_effect/artwork.png index 1c5d5defb7..31296ca909 100644 Binary files a/plugins/peak_controller_effect/artwork.png and b/plugins/peak_controller_effect/artwork.png differ diff --git a/plugins/peak_controller_effect/peak_controller_effect.cpp b/plugins/peak_controller_effect/peak_controller_effect.cpp index f9b4049c50..4069c941b8 100644 --- a/plugins/peak_controller_effect/peak_controller_effect.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect.cpp @@ -81,6 +81,7 @@ PeakControllerEffect::~PeakControllerEffect() if( idx >= 0 ) { PeakController::s_effects.remove( idx ); + engine::getSong()->removeController( m_autoController ); } } diff --git a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp index eb7e5191df..34ee79a117 100644 --- a/plugins/peak_controller_effect/peak_controller_effect_controls.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect_controls.cpp @@ -29,6 +29,7 @@ #include "PeakController.h" #include "peak_controller_effect_controls.h" #include "peak_controller_effect.h" +#include "preset_preview_play_handle.h" PeakControllerEffectControls:: @@ -66,7 +67,7 @@ void PeakControllerEffectControls::loadSettings( const QDomElement & _this ) } m_effect->m_effectId = effectId; - if( m_effect->m_autoController ) + if( m_effect->m_autoController && presetPreviewPlayHandle::isPreviewing() == false ) { delete m_effect->m_autoController; m_effect->m_autoController = 0; diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 9091cafef9..368a9779b6 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -87,7 +87,8 @@ sf2Instrument::sf2Instrument( InstrumentTrack * _instrument_track ) : m_font( NULL ), m_fontId( 0 ), m_filename( "" ), - m_lastMidiPitch( 8192 ), + m_lastMidiPitch( -1 ), + m_lastMidiPitchRange( -1 ), m_channel( 1 ), m_bankNum( 0, 0, 999, this, tr("Bank") ), m_patchNum( 0, 0, 127, this, tr("Patch") ), @@ -679,12 +680,21 @@ void sf2Instrument::play( sampleFrame * _working_buffer ) const fpp_t frames = engine::mixer()->framesPerPeriod(); m_synthMutex.lock(); - if( m_lastMidiPitch != instrumentTrack()->midiPitch() ) + + const int currentMidiPitch = instrumentTrack()->midiPitch(); + if( m_lastMidiPitch != currentMidiPitch ) { - m_lastMidiPitch = instrumentTrack()->midiPitch(); + m_lastMidiPitch = currentMidiPitch; fluid_synth_pitch_bend( m_synth, m_channel, m_lastMidiPitch ); } + const int currentMidiPitchRange = instrumentTrack()->midiPitchRange(); + if( m_lastMidiPitchRange != currentMidiPitchRange ) + { + m_lastMidiPitchRange = currentMidiPitchRange; + fluid_synth_pitch_wheel_sens( m_synth, m_channel, m_lastMidiPitchRange ); + } + if( m_internalSampleRate < engine::mixer()->processingSampleRate() && m_srcState != NULL ) { diff --git a/plugins/sf2_player/sf2_player.h b/plugins/sf2_player/sf2_player.h index 9034806054..691a2be833 100644 --- a/plugins/sf2_player/sf2_player.h +++ b/plugins/sf2_player/sf2_player.h @@ -129,6 +129,7 @@ private: int m_notesRunning[128]; sample_rate_t m_internalSampleRate; int m_lastMidiPitch; + int m_lastMidiPitchRange; int m_channel; lcdSpinBoxModel m_bankNum; diff --git a/plugins/triple_oscillator/artwork.png b/plugins/triple_oscillator/artwork.png index 7c61a87eca..b4940ae5e6 100644 Binary files a/plugins/triple_oscillator/artwork.png and b/plugins/triple_oscillator/artwork.png differ diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index e8f59c1f45..f47efe689a 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -310,13 +310,12 @@ void vestigeInstrument::play( sampleFrame * _buf ) -bool vestigeInstrument::handleMidiEvent( const midiEvent & _me, - const midiTime & _time ) +bool vestigeInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time ) { m_pluginMutex.lock(); if( m_plugin != NULL ) { - m_plugin->processMidiEvent( _me, _time ); + m_plugin->processMidiEvent( event, time ); } m_pluginMutex.unlock(); @@ -779,8 +778,7 @@ void VestigeInstrumentView::noteOffAll( void ) { for( int key = 0; key <= MidiMaxNote; ++key ) { - m_vi->m_plugin->processMidiEvent( - midiEvent( MidiNoteOff, 0, key, 0 ), 0 ); + m_vi->m_plugin->processMidiEvent( MidiEvent( MidiNoteOff, 0, key, 0 ), 0 ); } } m_vi->m_pluginMutex.unlock(); diff --git a/plugins/vestige/vestige.h b/plugins/vestige/vestige.h index 600e87e22c..b3e6703054 100644 --- a/plugins/vestige/vestige.h +++ b/plugins/vestige/vestige.h @@ -1,7 +1,7 @@ /* * vestige.h - instrument VeSTige for hosting VST-plugins * - * Copyright (c) 2005-2012 Tobias Doerffel + * Copyright (c) 2005-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -34,7 +34,6 @@ #include "Instrument.h" #include "InstrumentView.h" -#include "midi.h" #include "note.h" #include "knob.h" @@ -69,8 +68,7 @@ public: return true; } - virtual bool handleMidiEvent( const midiEvent & _me, - const midiTime & _time ); + virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time ); virtual PluginView * instantiateView( QWidget * _parent ); diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 9100de316a..9d1b278c35 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -89,7 +89,7 @@ struct ERect #include "lmms_basics.h" -#include "midi.h" +#include "Midi.h" #include "communication.h" #include "VST_sync_shm.h" @@ -132,8 +132,7 @@ public: virtual void process( const sampleFrame * _in, sampleFrame * _out ); - virtual void processMidiEvent( const midiEvent & _event, - const f_cnt_t _offset ); + virtual void processMidiEvent( const MidiEvent& event, const f_cnt_t offset ); // set given sample-rate for plugin virtual void updateSampleRate() @@ -774,16 +773,15 @@ void RemoteVstPlugin::process( const sampleFrame * _in, sampleFrame * _out ) // dispatcher-call, so we create static copies of the // data and post them #define MIDI_EVENT_BUFFER_COUNT 1024 - static char event_buf[sizeof( VstMidiEvent * ) * - MIDI_EVENT_BUFFER_COUNT + - sizeof( VstEvents )]; + static char eventsBuffer[sizeof( VstEvents ) + sizeof( VstMidiEvent * ) * MIDI_EVENT_BUFFER_COUNT]; static VstMidiEvent vme[MIDI_EVENT_BUFFER_COUNT]; - VstEvents * events = (VstEvents *) event_buf; + + VstEvents* events = (VstEvents *) eventsBuffer; events->reserved = 0; events->numEvents = m_midiEvents.size(); + int idx = 0; - for( VstMidiEventList::iterator it = m_midiEvents.begin(); - it != m_midiEvents.end(); ++it, ++idx ) + for( VstMidiEventList::iterator it = m_midiEvents.begin(); it != m_midiEvents.end(); ++it, ++idx ) { memcpy( &vme[idx], &*it, sizeof( VstMidiEvent ) ); events->events[idx] = (VstEvent *) &vme[idx]; @@ -831,36 +829,37 @@ void RemoteVstPlugin::process( const sampleFrame * _in, sampleFrame * _out ) -void RemoteVstPlugin::processMidiEvent( const midiEvent & _event, - const f_cnt_t _offset ) +void RemoteVstPlugin::processMidiEvent( const MidiEvent& event, const f_cnt_t offset ) { - VstMidiEvent event; + VstMidiEvent vme; - event.type = kVstMidiType; - event.byteSize = 24; - event.deltaFrames = _offset; - event.flags = 0; - event.detune = 0; - event.noteLength = 0; - event.noteOffset = 0; - event.noteOffVelocity = 0; - event.reserved1 = 0; - event.reserved2 = 0; - event.midiData[0] = _event.m_type + _event.m_channel; - switch( _event.m_type ) + vme.type = kVstMidiType; + vme.byteSize = 24; + vme.deltaFrames = offset; + vme.flags = 0; + vme.detune = 0; + vme.noteLength = 0; + vme.noteOffset = 0; + vme.noteOffVelocity = 0; + vme.reserved1 = 0; + vme.reserved2 = 0; + vme.midiData[0] = event.type() + event.channel(); + + switch( event.type() ) { case MidiPitchBend: - event.midiData[1] = _event.m_data.m_param[0] & 0x7f; - event.midiData[2] = _event.m_data.m_param[0] >> 7; + vme.midiData[1] = event.param( 0 ) & 0x7f; + vme.midiData[2] = event.param( 1 ) >> 7; break; // TODO: handle more special cases default: - event.midiData[1] = _event.key(); - event.midiData[2] = _event.velocity(); + vme.midiData[1] = event.key(); + vme.midiData[2] = event.velocity(); break; } - event.midiData[3] = 0; - m_midiEvents.push_back( event ); + vme.midiData[3] = 0; + + m_midiEvents.push_back( vme ); } diff --git a/plugins/zynaddsubfx/LocalZynAddSubFx.cpp b/plugins/zynaddsubfx/LocalZynAddSubFx.cpp index 24e4ff182e..6705bb33d0 100644 --- a/plugins/zynaddsubfx/LocalZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/LocalZynAddSubFx.cpp @@ -1,7 +1,7 @@ /* * LocalZynAddSubFx.cpp - local implementation of ZynAddSubFx plugin * - * Copyright (c) 2009-2013 Tobias Doerffel + * Copyright (c) 2009-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -190,47 +190,43 @@ void LocalZynAddSubFx::setLmmsWorkingDir( const std::string & _dir ) -void LocalZynAddSubFx::processMidiEvent( const midiEvent & _e ) +void LocalZynAddSubFx::processMidiEvent( const MidiEvent& event ) { // all functions are called while m_master->mutex is held static NULLMidiIn midiIn; - switch( _e.m_type ) + switch( event.type() ) { case MidiNoteOn: - if( _e.velocity() > 0 ) + if( event.velocity() > 0 ) { - if( _e.key() <= 0 || _e.key() >= 128 ) + if( event.key() <= 0 || event.key() >= 128 ) { break; } - if( m_runningNotes[_e.key()] > 0 ) + if( m_runningNotes[event.key()] > 0 ) { - m_master->NoteOff( _e.channel(), _e.key() ); + m_master->NoteOff( event.channel(), event.key() ); } - ++m_runningNotes[_e.key()]; - m_master->NoteOn( _e.channel(), _e.key(), _e.velocity() ); + ++m_runningNotes[event.key()]; + m_master->NoteOn( event.channel(), event.key(), event.velocity() ); break; } case MidiNoteOff: - if( _e.key() <= 0 || _e.key() >= 128 ) + if( event.key() <= 0 || event.key() >= 128 ) { break; } - if( --m_runningNotes[_e.key()] <= 0 ) + if( --m_runningNotes[event.key()] <= 0 ) { - m_master->NoteOff( _e.channel(), _e.key() ); + m_master->NoteOff( event.channel(), event.key() ); } break; case MidiPitchBend: - m_master->SetController( _e.channel(), C_pitchwheel, - _e.m_data.m_param[0] + - _e.m_data.m_param[1]*128-8192 ); + m_master->SetController( event.channel(), C_pitchwheel, event.pitchBend()-8192 ); break; case MidiControlChange: - m_master->SetController( _e.channel(), - midiIn.getcontroller( _e.m_data.m_param[0] ), - _e.m_data.m_param[1] ); + m_master->SetController( event.channel(), midiIn.getcontroller( event.controllerNumber() ), event.controllerValue() ); break; default: break; diff --git a/plugins/zynaddsubfx/LocalZynAddSubFx.h b/plugins/zynaddsubfx/LocalZynAddSubFx.h index 9d6d663453..3aeab8ba55 100644 --- a/plugins/zynaddsubfx/LocalZynAddSubFx.h +++ b/plugins/zynaddsubfx/LocalZynAddSubFx.h @@ -1,7 +1,7 @@ /* * LocalZynAddSubFx.h - local implementation of ZynAddSubFx plugin * - * Copyright (c) 2009 Tobias Doerffel + * Copyright (c) 2009-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -25,6 +25,7 @@ #ifndef _LOCAL_ZYNADDSUBFX_H #define _LOCAL_ZYNADDSUBFX_H +#include "MidiEvent.h" #include "note.h" class Master; @@ -48,7 +49,7 @@ public: void setPresetDir( const std::string & _dir ); void setLmmsWorkingDir( const std::string & _dir ); - void processMidiEvent( const midiEvent & _e ); + void processMidiEvent( const MidiEvent& event ); void processAudio( sampleFrame * _out ); diff --git a/plugins/zynaddsubfx/RemoteZynAddSubFx.cpp b/plugins/zynaddsubfx/RemoteZynAddSubFx.cpp index 29300bf751..5e25de9fa2 100644 --- a/plugins/zynaddsubfx/RemoteZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/RemoteZynAddSubFx.cpp @@ -1,7 +1,7 @@ /* * RemoteZynAddSubFx.cpp - ZynAddSubFx-embedding plugin * - * Copyright (c) 2008-2012 Tobias Doerffel + * Copyright (c) 2008-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -126,10 +126,9 @@ public: } // all functions are called while m_master->mutex is held - virtual void processMidiEvent( const midiEvent & _e, - const f_cnt_t /* _offset */ ) + virtual void processMidiEvent( const MidiEvent& event, const f_cnt_t /* _offset */ ) { - LocalZynAddSubFx::processMidiEvent( _e ); + LocalZynAddSubFx::processMidiEvent( event ); } diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index ad2dde50a4..0984bfecfa 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -340,14 +340,13 @@ void ZynAddSubFxInstrument::play( sampleFrame * _buf ) -bool ZynAddSubFxInstrument::handleMidiEvent( const midiEvent & _me, - const midiTime & _time ) +bool ZynAddSubFxInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time ) { // do not forward external MIDI Control Change events if the according // LED is not checked - if( _me.type() == MidiControlChange && - _me.sourcePort() != this && - m_forwardMidiCcModel.value() == false ) + if( event.type() == MidiControlChange && + event.sourcePort() != this && + m_forwardMidiCcModel.value() == false ) { return true; } @@ -355,11 +354,11 @@ bool ZynAddSubFxInstrument::handleMidiEvent( const midiEvent & _me, m_pluginMutex.lock(); if( m_remotePlugin ) { - m_remotePlugin->processMidiEvent( _me, 0 ); + m_remotePlugin->processMidiEvent( event, 0 ); } else { - m_plugin->processMidiEvent( _me ); + m_plugin->processMidiEvent( event ); } m_pluginMutex.unlock(); @@ -446,8 +445,7 @@ void ZynAddSubFxInstrument::initPlugin() void ZynAddSubFxInstrument::sendControlChange( MidiControllers midiCtl, float value ) { - handleMidiEvent( midiEvent( MidiControlChange, instrumentTrack()->midiPort()->realOutputChannel(), midiCtl, (int) value, this ), - midiTime() ); + handleMidiEvent( MidiEvent( MidiControlChange, instrumentTrack()->midiPort()->realOutputChannel(), midiCtl, (int) value, this ) ); } diff --git a/plugins/zynaddsubfx/ZynAddSubFx.h b/plugins/zynaddsubfx/ZynAddSubFx.h index f37ba857b4..8ea46a1248 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.h +++ b/plugins/zynaddsubfx/ZynAddSubFx.h @@ -70,8 +70,7 @@ public: virtual void play( sampleFrame * _working_buffer ); - virtual bool handleMidiEvent( const midiEvent & _me, - const midiTime & _time ); + virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ); virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); virtual void loadSettings( const QDomElement & _this ); diff --git a/plugins/zynaddsubfx/artwork.png b/plugins/zynaddsubfx/artwork.png index 7d158bdaa7..2ef0b57056 100644 Binary files a/plugins/zynaddsubfx/artwork.png and b/plugins/zynaddsubfx/artwork.png differ diff --git a/plugins/zynaddsubfx/src/Params/Controller.cpp b/plugins/zynaddsubfx/src/Params/Controller.cpp index 9bfa6b47d9..e3fb70d8cf 100644 --- a/plugins/zynaddsubfx/src/Params/Controller.cpp +++ b/plugins/zynaddsubfx/src/Params/Controller.cpp @@ -35,7 +35,7 @@ Controller::~Controller() void Controller::defaults() { - setpitchwheelbendrange(200); //2 halftones + setpitchwheelbendrange(100); //2 halftones expression.receive = 1; panning.depth = 64; filtercutoff.depth = 64; diff --git a/plugins/zynaddsubfx/src/Seq/Sequencer.cpp b/plugins/zynaddsubfx/src/Seq/Sequencer.cpp index 6dfde4679b..c11e68a7c9 100644 --- a/plugins/zynaddsubfx/src/Seq/Sequencer.cpp +++ b/plugins/zynaddsubfx/src/Seq/Sequencer.cpp @@ -157,10 +157,9 @@ void Sequencer::resettime(timestruct *t) t->abs = 0.0; t->rel = 0.0; - timeval tval; - t->last = 0.0; #ifndef OS_WINDOWS + timeval tval; if(gettimeofday(&tval, NULL) == 0) t->last = tval.tv_sec + tval.tv_usec * 0.000001; #endif @@ -168,9 +167,9 @@ void Sequencer::resettime(timestruct *t) void Sequencer::updatecounter(timestruct *t) { - timeval tval; double current = 0.0; #ifndef OS_WINDOWS + timeval tval; if(gettimeofday(&tval, NULL) == 0) current = tval.tv_sec + tval.tv_usec * 0.000001; #endif diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index a9a3b5147b..56791ade4f 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -253,7 +253,7 @@ void AutomatableModel::setRange( const float min, const float max, setStep( step ); // re-adjust value - setInitValue( value() ); + setValue( value() ); emit propertiesChanged(); } diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 4babc3c50c..1ce04941ce 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -45,7 +45,7 @@ AutomationPattern::AutomationPattern( AutomationTrack * _auto_track ) : m_tension( "1.0" ), m_progressionType( DiscreteProgression ) { - changeLength( midiTime( 1, 0 ) ); + changeLength( MidiTime( 1, 0 ) ); } @@ -166,7 +166,7 @@ const AutomatableModel * AutomationPattern::firstObject() const //TODO: Improve this -midiTime AutomationPattern::length() const +MidiTime AutomationPattern::length() const { tick_t max_length = 0; @@ -175,19 +175,19 @@ midiTime AutomationPattern::length() const { max_length = qMax( max_length, it.key() ); } - return midiTime( qMax( midiTime( max_length ).getTact() + 1, 1 ), 0 ); + return MidiTime( qMax( MidiTime( max_length ).getTact() + 1, 1 ), 0 ); } -midiTime AutomationPattern::putValue( const midiTime & _time, +MidiTime AutomationPattern::putValue( const MidiTime & _time, const float _value, const bool _quant_pos ) { cleanObjects(); - midiTime newTime = _quant_pos && engine::automationEditor() ? + MidiTime newTime = _quant_pos && engine::automationEditor() ? note::quantized( _time, engine::automationEditor()->quantization() ) : _time; @@ -215,7 +215,7 @@ midiTime AutomationPattern::putValue( const midiTime & _time, -void AutomationPattern::removeValue( const midiTime & _time ) +void AutomationPattern::removeValue( const MidiTime & _time ) { cleanObjects(); @@ -240,7 +240,7 @@ void AutomationPattern::removeValue( const midiTime & _time ) -float AutomationPattern::valueAt( const midiTime & _time ) const +float AutomationPattern::valueAt( const MidiTime & _time ) const { if( m_timeMap.isEmpty() ) { @@ -306,7 +306,7 @@ float AutomationPattern::valueAt( timeMap::const_iterator v, int offset ) const -float *AutomationPattern::valuesAfter( const midiTime & _time ) const +float *AutomationPattern::valuesAfter( const MidiTime & _time ) const { timeMap::ConstIterator v = m_timeMap.lowerBound( _time ); if( v == m_timeMap.end() || (v+1) == m_timeMap.end() ) @@ -417,7 +417,7 @@ const QString AutomationPattern::name() const -void AutomationPattern::processMidiTime( const midiTime & _time ) +void AutomationPattern::processMidiTime( const MidiTime & _time ) { if( _time >= 0 && hasAutomation() ) { diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index 1de453df81..985fd31528 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -477,7 +477,7 @@ void InstrumentFunctionArpeggio::processNote( notePlayHandle * _n ) } // create new arp-note - note new_note( midiTime( 0 ), midiTime( 0 ), + note new_note( MidiTime( 0 ), MidiTime( 0 ), sub_note_key, (volume_t) qRound( _n->getVolume() * vol_level ), diff --git a/src/core/InstrumentSoundShaping.cpp b/src/core/InstrumentSoundShaping.cpp index 535a0d99d2..16a6f50508 100644 --- a/src/core/InstrumentSoundShaping.cpp +++ b/src/core/InstrumentSoundShaping.cpp @@ -326,7 +326,8 @@ f_cnt_t InstrumentSoundShaping::releaseFrames() const { f_cnt_t ret_val = m_envLfoParameters[Volume]->isUsed() ? m_envLfoParameters[Volume]->releaseFrames() : 0; - if( m_instrumentTrack->instrument()->desiredReleaseFrames() > ret_val ) + if( m_instrumentTrack->instrument() && + m_instrumentTrack->instrument()->desiredReleaseFrames() > ret_val ) { ret_val = m_instrumentTrack->instrument()->desiredReleaseFrames(); } diff --git a/src/core/Piano.cpp b/src/core/Piano.cpp index 3bd85ee8dc..584362f46f 100644 --- a/src/core/Piano.cpp +++ b/src/core/Piano.cpp @@ -38,6 +38,7 @@ #include "Piano.h" #include "InstrumentTrack.h" +#include "MidiEvent.h" #include "MidiEventProcessor.h" @@ -96,7 +97,7 @@ void Piano::handleKeyPress( int key, int midiVelocity ) { if( isValidKey( key ) ) { - m_midiEvProc->processInEvent( midiEvent( MidiNoteOn, 0, key, midiVelocity ), midiTime() ); + m_midiEvProc->processInEvent( MidiEvent( MidiNoteOn, 0, key, midiVelocity ) ); m_pressedKeys[key] = true; } } @@ -113,7 +114,7 @@ void Piano::handleKeyRelease( int key ) { if( isValidKey( key ) ) { - m_midiEvProc->processInEvent( midiEvent( MidiNoteOff, 0, key, 0 ), midiTime() ); + m_midiEvProc->processInEvent( MidiEvent( MidiNoteOff, 0, key, 0 ) ); m_pressedKeys[key] = false; } } diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index 24e047d995..0128444e8b 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -1,7 +1,7 @@ /* * RemotePlugin.cpp - base class providing RPC like mechanisms * - * Copyright (c) 2008-2010 Tobias Doerffel + * Copyright (c) 2008-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -281,14 +281,14 @@ bool RemotePlugin::process( const sampleFrame * _in_buf, -void RemotePlugin::processMidiEvent( const midiEvent & _e, +void RemotePlugin::processMidiEvent( const MidiEvent & _e, const f_cnt_t _offset ) { message m( IdMidiEvent ); - m.addInt( _e.m_type ); - m.addInt( _e.m_channel ); - m.addInt( _e.m_data.m_param[0] ); - m.addInt( _e.m_data.m_param[1] ); + m.addInt( _e.type() ); + m.addInt( _e.channel() ); + m.addInt( _e.param( 0 ) ); + m.addInt( _e.param( 1 ) ); m.addInt( _offset ); lock(); sendMessage( m ); diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 5b21b220c1..674a0a1012 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -38,6 +38,7 @@ #include +#define OV_EXCLUDE_STATIC_CALLBACKS #ifdef LMMS_HAVE_OGGVORBIS #include #endif diff --git a/src/core/SampleRecordHandle.cpp b/src/core/SampleRecordHandle.cpp index 9d0cff4ad1..674af8d938 100644 --- a/src/core/SampleRecordHandle.cpp +++ b/src/core/SampleRecordHandle.cpp @@ -73,7 +73,7 @@ void SampleRecordHandle::play( sampleFrame * /*_working_buffer*/ ) writeBuffer( recbuf, frames ); m_framesRecorded += frames; - midiTime len = (tick_t)( m_framesRecorded / engine::framesPerTick() ); + MidiTime len = (tick_t)( m_framesRecorded / engine::framesPerTick() ); if( len > m_minLength ) { // m_tco->changeLength( len ); diff --git a/src/core/bb_track_container.cpp b/src/core/bb_track_container.cpp index d199f8454d..0cbcef43b1 100644 --- a/src/core/bb_track_container.cpp +++ b/src/core/bb_track_container.cpp @@ -54,7 +54,7 @@ bbTrackContainer::~bbTrackContainer() -bool bbTrackContainer::play( midiTime _start, fpp_t _frames, +bool bbTrackContainer::play( MidiTime _start, fpp_t _frames, f_cnt_t _offset, int _tco_num ) { bool played_a_note = false; @@ -63,7 +63,7 @@ bool bbTrackContainer::play( midiTime _start, fpp_t _frames, return false; } - _start = _start % ( lengthOfBB( _tco_num ) * midiTime::ticksPerTact() ); + _start = _start % ( lengthOfBB( _tco_num ) * MidiTime::ticksPerTact() ); TrackList tl = tracks(); for( TrackList::iterator it = tl.begin(); it != tl.end(); ++it ) @@ -99,7 +99,7 @@ void bbTrackContainer::updateAfterTrackAdd() tact_t bbTrackContainer::lengthOfBB( int _bb ) { - midiTime max_length = midiTime::ticksPerTact(); + MidiTime max_length = MidiTime::ticksPerTact(); const TrackList & tl = tracks(); for( TrackList::const_iterator it = tl.begin(); it != tl.end(); ++it ) @@ -172,7 +172,7 @@ void bbTrackContainer::fixIncorrectPositions() { for( int i = 0; i < numOfBBs(); ++i ) { - ( *it )->getTCO( i )->movePosition( midiTime( i, 0 ) ); + ( *it )->getTCO( i )->movePosition( MidiTime( i, 0 ) ); } } } @@ -252,10 +252,10 @@ void bbTrackContainer::createTCOsForBB( int _bb ) { while( tl[i]->numOfTCOs() < _bb + 1 ) { - midiTime position = midiTime( tl[i]->numOfTCOs(), 0 ); + MidiTime position = MidiTime( tl[i]->numOfTCOs(), 0 ); trackContentObject * tco = tl[i]->createTCO( position ); tco->movePosition( position ); - tco->changeLength( midiTime( 1, 0 ) ); + tco->changeLength( MidiTime( 1, 0 ) ); } } } diff --git a/src/core/midi/MidiAlsaSeq.cpp b/src/core/midi/MidiAlsaSeq.cpp index 95b351197b..662dc43eac 100644 --- a/src/core/midi/MidiAlsaSeq.cpp +++ b/src/core/midi/MidiAlsaSeq.cpp @@ -31,6 +31,7 @@ #include "gui_templates.h" #include "song.h" #include "MidiPort.h" +#include "MidiTime.h" #include "note.h" @@ -160,73 +161,70 @@ QString MidiAlsaSeq::probeDevice() -void MidiAlsaSeq::processOutEvent( const midiEvent & _me, - const midiTime & _time, - const MidiPort * _port ) +void MidiAlsaSeq::processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port ) { // HACK!!! - need a better solution which isn't that easy since we // cannot store const-ptrs in our map because we need to call non-const // methods of MIDI-port - it's a mess... - MidiPort * p = const_cast( _port ); + MidiPort* p = const_cast( port ); snd_seq_event_t ev; snd_seq_ev_clear( &ev ); snd_seq_ev_set_source( &ev, ( m_portIDs[p][1] != -1 ) ? m_portIDs[p][1] : m_portIDs[p][0] ); snd_seq_ev_set_subs( &ev ); - snd_seq_ev_schedule_tick( &ev, m_queueID, 1, static_cast( _time ) ); + snd_seq_ev_schedule_tick( &ev, m_queueID, 1, static_cast( time ) ); ev.queue = m_queueID; - switch( _me.m_type ) + switch( event.type() ) { case MidiNoteOn: snd_seq_ev_set_noteon( &ev, - _me.channel(), - _me.key() + KeysPerOctave, - _me.velocity() ); + event.channel(), + event.key() + KeysPerOctave, + event.velocity() ); break; case MidiNoteOff: snd_seq_ev_set_noteoff( &ev, - _me.channel(), - _me.key() + KeysPerOctave, - _me.velocity() ); + event.channel(), + event.key() + KeysPerOctave, + event.velocity() ); break; case MidiKeyPressure: snd_seq_ev_set_keypress( &ev, - _me.channel(), - _me.key() + KeysPerOctave, - _me.velocity() ); + event.channel(), + event.key() + KeysPerOctave, + event.velocity() ); break; case MidiControlChange: snd_seq_ev_set_controller( &ev, - _me.channel(), - _me.m_data.m_param[0], - _me.m_data.m_param[1] ); + event.channel(), + event.controllerNumber(), + event.controllerValue() ); break; case MidiProgramChange: snd_seq_ev_set_pgmchange( &ev, - _me.channel(), - _me.m_data.m_param[0] ); + event.channel(), + event.program() ); break; case MidiChannelPressure: snd_seq_ev_set_chanpress( &ev, - _me.channel(), - _me.m_data.m_param[0] ); + event.channel(), + event.channelPressure() ); break; case MidiPitchBend: snd_seq_ev_set_pitchbend( &ev, - _me.channel(), - _me.m_data.m_param[0] - 8192 ); + event.channel(), + event.param( 0 ) - 8192 ); break; default: - fprintf( stderr, "ALSA-sequencer: unhandled output " - "event %d\n", (int) _me.m_type ); + qWarning( "MidiAlsaSeq: unhandled output event %d\n", (int) event.type() ); return; } @@ -353,7 +351,7 @@ void MidiAlsaSeq::removePort( MidiPort * _port ) -QString MidiAlsaSeq::sourcePortName( const midiEvent & _event ) const +QString MidiAlsaSeq::sourcePortName( const MidiEvent & _event ) const { if( _event.sourcePort() ) { @@ -535,70 +533,70 @@ void MidiAlsaSeq::run() switch( ev->type ) { case SND_SEQ_EVENT_NOTEON: - dest->processInEvent( midiEvent( MidiNoteOn, + dest->processInEvent( MidiEvent( MidiNoteOn, ev->data.note.channel, ev->data.note.note - KeysPerOctave, ev->data.note.velocity, source ), - midiTime( ev->time.tick ) ); + MidiTime( ev->time.tick ) ); break; case SND_SEQ_EVENT_NOTEOFF: - dest->processInEvent( midiEvent( MidiNoteOff, + dest->processInEvent( MidiEvent( MidiNoteOff, ev->data.note.channel, ev->data.note.note - KeysPerOctave, ev->data.note.velocity, source ), - midiTime( ev->time.tick) ); + MidiTime( ev->time.tick) ); break; case SND_SEQ_EVENT_KEYPRESS: - dest->processInEvent( midiEvent( + dest->processInEvent( MidiEvent( MidiKeyPressure, ev->data.note.channel, ev->data.note.note - KeysPerOctave, ev->data.note.velocity, source - ), midiTime() ); + ), MidiTime() ); break; case SND_SEQ_EVENT_CONTROLLER: - dest->processInEvent( midiEvent( + dest->processInEvent( MidiEvent( MidiControlChange, ev->data.control.channel, ev->data.control.param, ev->data.control.value, source ), - midiTime() ); + MidiTime() ); break; case SND_SEQ_EVENT_PGMCHANGE: - dest->processInEvent( midiEvent( + dest->processInEvent( MidiEvent( MidiProgramChange, ev->data.control.channel, ev->data.control.param, ev->data.control.value, source ), - midiTime() ); + MidiTime() ); break; case SND_SEQ_EVENT_CHANPRESS: - dest->processInEvent( midiEvent( + dest->processInEvent( MidiEvent( MidiChannelPressure, ev->data.control.channel, ev->data.control.param, ev->data.control.value, source ), - midiTime() ); + MidiTime() ); break; case SND_SEQ_EVENT_PITCHBEND: - dest->processInEvent( midiEvent( MidiPitchBend, + dest->processInEvent( MidiEvent( MidiPitchBend, ev->data.control.channel, ev->data.control.value + 8192, 0, source ), - midiTime() ); + MidiTime() ); break; case SND_SEQ_EVENT_SENSING: diff --git a/src/core/midi/MidiClient.cpp b/src/core/midi/MidiClient.cpp index 8e3895d24e..673d5f20d2 100644 --- a/src/core/midi/MidiClient.cpp +++ b/src/core/midi/MidiClient.cpp @@ -25,7 +25,6 @@ #include "MidiClient.h" #include "MidiPort.h" -#include "templates.h" #include "note.h" @@ -44,32 +43,32 @@ MidiClient::~MidiClient() -void MidiClient::applyPortMode( MidiPort * ) +void MidiClient::applyPortMode( MidiPort* ) { } -void MidiClient::applyPortName( MidiPort * ) +void MidiClient::applyPortName( MidiPort* ) { } -void MidiClient::addPort( MidiPort * _port ) +void MidiClient::addPort( MidiPort* port ) { - m_midiPorts.push_back( _port ); + m_midiPorts.push_back( port ); } -void MidiClient::removePort( MidiPort * _port ) +void MidiClient::removePort( MidiPort* port ) { QVector::Iterator it = - qFind( m_midiPorts.begin(), m_midiPorts.end(), _port ); + qFind( m_midiPorts.begin(), m_midiPorts.end(), port ); if( it != m_midiPorts.end() ) { m_midiPorts.erase( it ); @@ -79,14 +78,14 @@ void MidiClient::removePort( MidiPort * _port ) -void MidiClient::subscribeReadablePort( MidiPort *, const QString & , bool ) +void MidiClient::subscribeReadablePort( MidiPort*, const QString& , bool ) { } -void MidiClient::subscribeWritablePort( MidiPort * , const QString & , bool ) +void MidiClient::subscribeWritablePort( MidiPort* , const QString& , bool ) { } @@ -124,7 +123,7 @@ void MidiClientRaw::parseData( const unsigned char c ) { if( c == MidiSystemReset ) { - m_midiParseData.m_midiEvent.m_type = MidiSystemReset; + m_midiParseData.m_midiEvent.setType( MidiSystemReset ); m_midiParseData.m_status = 0; processParsedEvent(); } @@ -206,34 +205,30 @@ void MidiClientRaw::parseData( const unsigned char c ) * We simply keep the status as it is, just reset the parameter counter. * If another status byte comes in, it will overwrite the status. */ - m_midiParseData.m_midiEvent.m_type = static_cast( m_midiParseData.m_status ); - m_midiParseData.m_midiEvent.m_channel = m_midiParseData.m_channel; + m_midiParseData.m_midiEvent.setType( static_cast( m_midiParseData.m_status ) ); + m_midiParseData.m_midiEvent.setChannel( m_midiParseData.m_channel ); m_midiParseData.m_bytes = 0; /* Related to running status! */ - switch( m_midiParseData.m_midiEvent.m_type ) + switch( m_midiParseData.m_midiEvent.type() ) { case MidiNoteOff: case MidiNoteOn: case MidiKeyPressure: case MidiProgramChange: case MidiChannelPressure: - m_midiParseData.m_midiEvent.m_data.m_param[0] = - m_midiParseData.m_buffer[0] - KeysPerOctave; - m_midiParseData.m_midiEvent.m_data.m_param[1] = - m_midiParseData.m_buffer[1]; + m_midiParseData.m_midiEvent.setKey( m_midiParseData.m_buffer[0] - KeysPerOctave ); + m_midiParseData.m_midiEvent.setVelocity( m_midiParseData.m_buffer[1] ); break; case MidiControlChange: - m_midiParseData.m_midiEvent.m_data.m_param[0] = m_midiParseData.m_buffer[0]; - m_midiParseData.m_midiEvent.m_data.m_param[1] = m_midiParseData.m_buffer[1]; + m_midiParseData.m_midiEvent.setControllerNumber( m_midiParseData.m_buffer[0] ); + m_midiParseData.m_midiEvent.setControllerValue( m_midiParseData.m_buffer[1] ); break; case MidiPitchBend: // Pitch-bend is transmitted with 14-bit precision. // Note: '|' does here the same as '+' (no common bits), // but might be faster - m_midiParseData.m_midiEvent.m_data.m_param[0] = - ( ( m_midiParseData.m_buffer[1] * 128 ) | - m_midiParseData.m_buffer[0] ); + m_midiParseData.m_midiEvent.setPitchBend( ( m_midiParseData.m_buffer[1] * 128 ) | m_midiParseData.m_buffer[0] ); break; default: @@ -251,33 +246,29 @@ void MidiClientRaw::processParsedEvent() { for( int i = 0; i < m_midiPorts.size(); ++i ) { - m_midiPorts[i]->processInEvent( m_midiParseData.m_midiEvent, - midiTime() ); + m_midiPorts[i]->processInEvent( m_midiParseData.m_midiEvent ); } } -void MidiClientRaw::processOutEvent( const midiEvent & _me, - const midiTime & , - const MidiPort * _port ) +void MidiClientRaw::processOutEvent( const MidiEvent& event, const MidiTime & , const MidiPort* port ) { // TODO: also evaluate _time and queue event if necessary - switch( _me.m_type ) + switch( event.type() ) { case MidiNoteOn: case MidiNoteOff: case MidiKeyPressure: - sendByte( _me.m_type | _me.channel() ); - sendByte( _me.m_data.m_param[0] + KeysPerOctave ); - sendByte( tLimit( (int) _me.m_data.m_param[1], - 0, 127 ) ); + sendByte( event.type() | event.channel() ); + sendByte( event.key() + KeysPerOctave ); + sendByte( event.velocity() ); break; default: qWarning( "MidiClientRaw: unhandled MIDI-event %d\n", - (int) _me.m_type ); + (int) event.type() ); break; } } diff --git a/src/core/midi/MidiController.cpp b/src/core/midi/MidiController.cpp index d323e6e7fc..5e65b5cd06 100644 --- a/src/core/midi/MidiController.cpp +++ b/src/core/midi/MidiController.cpp @@ -73,20 +73,19 @@ void MidiController::updateName() -void MidiController::processInEvent( const midiEvent & _me, - const midiTime & _time ) +void MidiController::processInEvent( const MidiEvent& event, const MidiTime& time ) { unsigned char controllerNum; - switch( _me.m_type ) + switch( event.type() ) { case MidiControlChange: - controllerNum = _me.m_data.m_bytes[0] & 0x7F; + controllerNum = event.controllerNumber(); if( m_midiPort.inputController() == controllerNum + 1 && - ( m_midiPort.inputChannel() == _me.m_channel + 1 || + ( m_midiPort.inputChannel() == event.channel() + 1 || m_midiPort.inputChannel() == 0 ) ) { - unsigned char val = _me.m_data.m_bytes[2] & 0x7F; + unsigned char val = event.controllerValue(); m_lastValue = (float)( val ) / 127.0f; emit valueChanged(); } diff --git a/src/core/midi/MidiPort.cpp b/src/core/midi/MidiPort.cpp index eb69493565..ffa2c97dd7 100644 --- a/src/core/midi/MidiPort.cpp +++ b/src/core/midi/MidiPort.cpp @@ -2,7 +2,7 @@ * MidiPort.cpp - abstraction of MIDI-ports which are part of LMMS's MIDI- * sequencing system * - * Copyright (c) 2005-2013 Tobias Doerffel + * Copyright (c) 2005-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -31,31 +31,25 @@ -MidiPort::MidiPort( const QString & _name, MidiClient * _mc, - MidiEventProcessor * _mep, Model * _parent, - Modes _mode ) : - Model( _parent ), +MidiPort::MidiPort( const QString& name, + MidiClient* client, + MidiEventProcessor* eventProcessor, + Model* parent, + Mode mode ) : + Model( parent ), m_readablePortsMenu( NULL ), m_writablePortsMenu( NULL ), - m_midiClient( _mc ), - m_midiEventProcessor( _mep ), - m_mode( _mode ), - m_inputChannelModel( 0, 0, MidiChannelCount, this, - tr( "Input channel" ) ), - m_outputChannelModel( 1, 1, MidiChannelCount, this, - tr( "Output channel" ) ), - m_inputControllerModel( 0, 0, MidiControllerCount, this, - tr( "Input controller" ) ), - m_outputControllerModel( 0, 0, MidiControllerCount, this, - tr( "Output controller" ) ), - m_fixedInputVelocityModel( -1, -1, MidiMaxVelocity, this, - tr( "Fixed input velocity" ) ), - m_fixedOutputVelocityModel( -1, -1, MidiMaxVelocity, this, - tr( "Fixed output velocity" ) ), - m_fixedOutputNoteModel( -1, -1, MidiMaxNote, this, - tr( "Fixed output note" ) ), - m_outputProgramModel( 1, 1, MidiProgramCount, this, - tr( "Output MIDI program" ) ), + m_midiClient( client ), + m_midiEventProcessor( eventProcessor ), + m_mode( mode ), + m_inputChannelModel( 0, 0, MidiChannelCount, this, tr( "Input channel" ) ), + m_outputChannelModel( 1, 1, MidiChannelCount, this, tr( "Output channel" ) ), + m_inputControllerModel( 0, 0, MidiControllerCount, this, tr( "Input controller" ) ), + m_outputControllerModel( 0, 0, MidiControllerCount, this, tr( "Output controller" ) ), + m_fixedInputVelocityModel( -1, -1, MidiMaxVelocity, this, tr( "Fixed input velocity" ) ), + m_fixedOutputVelocityModel( -1, -1, MidiMaxVelocity, this, tr( "Fixed output velocity" ) ), + m_fixedOutputNoteModel( -1, -1, MidiMaxNote, this, tr( "Fixed output note" ) ), + m_outputProgramModel( 1, 1, MidiProgramCount, this, tr( "Output MIDI program" ) ), m_readableModel( false, this, tr( "Receive MIDI-events" ) ), m_writableModel( false, this, tr( "Send MIDI-events" ) ) { @@ -64,12 +58,9 @@ MidiPort::MidiPort( const QString & _name, MidiClient * _mc, m_readableModel.setValue( m_mode == Input || m_mode == Duplex ); m_writableModel.setValue( m_mode == Output || m_mode == Duplex ); - connect( &m_readableModel, SIGNAL( dataChanged() ), - this, SLOT( updateMidiPortMode() ) ); - connect( &m_writableModel, SIGNAL( dataChanged() ), - this, SLOT( updateMidiPortMode() ) ); - connect( &m_outputProgramModel, SIGNAL( dataChanged() ), - this, SLOT( updateOutputProgram() ) ); + connect( &m_readableModel, SIGNAL( dataChanged() ), this, SLOT( updateMidiPortMode() ) ); + connect( &m_writableModel, SIGNAL( dataChanged() ), this, SLOT( updateMidiPortMode() ) ); + connect( &m_outputProgramModel, SIGNAL( dataChanged() ), this, SLOT( updateOutputProgram() ) ); // when using with non-raw-clients we can provide buttons showing @@ -80,10 +71,8 @@ MidiPort::MidiPort( const QString & _name, MidiClient * _mc, updateWritablePorts(); // we want to get informed about port-changes! - m_midiClient->connectRPChanged( this, - SLOT( updateReadablePorts() ) ); - m_midiClient->connectWPChanged( this, - SLOT( updateWritablePorts() ) ); + m_midiClient->connectRPChanged( this, SLOT( updateReadablePorts() ) ); + m_midiClient->connectWPChanged( this, SLOT( updateWritablePorts() ) ); } updateMidiPortMode(); @@ -105,109 +94,99 @@ MidiPort::~MidiPort() -void MidiPort::setName( const QString & _name ) +void MidiPort::setName( const QString& name ) { - setDisplayName( _name ); + setDisplayName( name ); m_midiClient->applyPortName( this ); } -void MidiPort::setMode( Modes _mode ) +void MidiPort::setMode( Mode mode ) { - m_mode = _mode; + m_mode = mode; m_midiClient->applyPortMode( this ); } -void MidiPort::processInEvent( const midiEvent & _me, const midiTime & _time ) +void MidiPort::processInEvent( const MidiEvent& event, const MidiTime& time ) { // mask event - if( inputEnabled() && - ( inputChannel()-1 == _me.m_channel || inputChannel() == 0 ) ) + if( isInputEnabled() && + ( inputChannel() == 0 || inputChannel()-1 == event.channel() ) ) { - midiEvent ev = _me; - if( _me.m_type == MidiNoteOn || - _me.m_type == MidiNoteOff || - _me.m_type == MidiKeyPressure ) + MidiEvent inEvent = event; + if( event.type() == MidiNoteOn || + event.type() == MidiNoteOff || + event.type() == MidiKeyPressure ) { - ev.key() = ev.key() + KeysPerOctave; - if( ev.key() < 0 || ev.key() >= NumKeys ) + inEvent.setKey( inEvent.key() + KeysPerOctave ); + if( inEvent.key() < 0 || inEvent.key() >= NumKeys ) { return; } } - if( fixedInputVelocity() >= 0 && _me.velocity() > 0 ) + if( fixedInputVelocity() >= 0 && inEvent.velocity() > 0 ) { - ev.velocity() = fixedInputVelocity(); + inEvent.setVelocity( fixedInputVelocity() ); } - ev.setFromMidiPort( true ); - m_midiEventProcessor->processInEvent( ev, _time ); + m_midiEventProcessor->processInEvent( inEvent, time ); } } -void MidiPort::processOutEvent( const midiEvent & _me, const midiTime & _time ) +void MidiPort::processOutEvent( const MidiEvent& event, const MidiTime& time ) { // mask event - if( outputEnabled() && realOutputChannel() == _me.m_channel ) + if( isOutputEnabled() && realOutputChannel() == event.channel() ) { - midiEvent ev = _me; - // we use/display MIDI channels 1...16 but we need 0...15 for - // the outside world - // We are already in "real" MIDI channel space here - /* if( ev.m_channel > 0 ) - { - --ev.m_channel; - } */ - if( ( _me.m_type == MidiNoteOn || _me.m_type == MidiNoteOff ) && + MidiEvent outEvent = event; + + if( ( event.type() == MidiNoteOn || event.type() == MidiNoteOff ) && fixedOutputNote() >= 0 ) { // Convert MIDI note number (from spinbox) -> LMMS note number // that will be converted back when outputted. - ev.key() = fixedOutputNote() - KeysPerOctave; + outEvent.setKey( fixedOutputNote() - KeysPerOctave ); } - if( fixedOutputVelocity() >= 0 && _me.velocity() > 0 && - ( _me.m_type == MidiNoteOn || - _me.m_type == MidiKeyPressure ) ) + + if( fixedOutputVelocity() >= 0 && event.velocity() > 0 && + ( event.type() == MidiNoteOn || event.type() == MidiKeyPressure ) ) { - ev.velocity() = fixedOutputVelocity(); + outEvent.setVelocity( fixedOutputVelocity() ); } - m_midiClient->processOutEvent( ev, _time, this ); + + m_midiClient->processOutEvent( outEvent, time, this ); } } -void MidiPort::saveSettings( QDomDocument & _doc, QDomElement & _this ) +void MidiPort::saveSettings( QDomDocument& doc, QDomElement& thisElement ) { - m_inputChannelModel.saveSettings( _doc, _this, "inputchannel" ); - m_outputChannelModel.saveSettings( _doc, _this, "outputchannel" ); - m_inputControllerModel.saveSettings( _doc, _this, "inputcontroller" ); - m_outputControllerModel.saveSettings( _doc, _this, "outputcontroller" ); - m_fixedInputVelocityModel.saveSettings( _doc, _this, - "fixedinputvelocity" ); - m_fixedOutputVelocityModel.saveSettings( _doc, _this, - "fixedoutputvelocity" ); - m_fixedOutputNoteModel.saveSettings( _doc, _this, - "fixedoutputnote" ); - m_outputProgramModel.saveSettings( _doc, _this, "outputprogram" ); - m_readableModel.saveSettings( _doc, _this, "readable" ); - m_writableModel.saveSettings( _doc, _this, "writable" ); + m_inputChannelModel.saveSettings( doc, thisElement, "inputchannel" ); + m_outputChannelModel.saveSettings( doc, thisElement, "outputchannel" ); + m_inputControllerModel.saveSettings( doc, thisElement, "inputcontroller" ); + m_outputControllerModel.saveSettings( doc, thisElement, "outputcontroller" ); + m_fixedInputVelocityModel.saveSettings( doc, thisElement, "fixedinputvelocity" ); + m_fixedOutputVelocityModel.saveSettings( doc, thisElement, "fixedoutputvelocity" ); + m_fixedOutputNoteModel.saveSettings( doc, thisElement, "fixedoutputnote" ); + m_outputProgramModel.saveSettings( doc, thisElement, "outputprogram" ); + m_readableModel.saveSettings( doc, thisElement, "readable" ); + m_writableModel.saveSettings( doc, thisElement, "writable" ); - if( inputEnabled() ) + if( isInputEnabled() ) { QString rp; - for( Map::ConstIterator it = m_readablePorts.begin(); - it != m_readablePorts.end(); ++it ) + for( Map::ConstIterator it = m_readablePorts.begin(); it != m_readablePorts.end(); ++it ) { if( it.value() ) { @@ -219,14 +198,13 @@ void MidiPort::saveSettings( QDomDocument & _doc, QDomElement & _this ) { rp.truncate( rp.length() - 1 ); } - _this.setAttribute( "inports", rp ); + thisElement.setAttribute( "inports", rp ); } - if( outputEnabled() ) + if( isOutputEnabled() ) { QString wp; - for( Map::ConstIterator it = m_writablePorts.begin(); - it != m_writablePorts.end(); ++it ) + for( Map::ConstIterator it = m_writablePorts.begin(); it != m_writablePorts.end(); ++it ) { if( it.value() ) { @@ -238,32 +216,31 @@ void MidiPort::saveSettings( QDomDocument & _doc, QDomElement & _this ) { wp.truncate( wp.length() - 1 ); } - _this.setAttribute( "outports", wp ); + thisElement.setAttribute( "outports", wp ); } } -void MidiPort::loadSettings( const QDomElement & _this ) +void MidiPort::loadSettings( const QDomElement& thisElement ) { - m_inputChannelModel.loadSettings( _this, "inputchannel" ); - m_outputChannelModel.loadSettings( _this, "outputchannel" ); - m_inputControllerModel.loadSettings( _this, "inputcontroller" ); - m_outputControllerModel.loadSettings( _this, "outputcontroller" ); - m_fixedInputVelocityModel.loadSettings( _this, "fixedinputvelocity" ); - m_fixedOutputVelocityModel.loadSettings( _this, "fixedoutputvelocity" ); - m_outputProgramModel.loadSettings( _this, "outputprogram" ); - m_readableModel.loadSettings( _this, "readable" ); - m_writableModel.loadSettings( _this, "writable" ); + m_inputChannelModel.loadSettings( thisElement, "inputchannel" ); + m_outputChannelModel.loadSettings( thisElement, "outputchannel" ); + m_inputControllerModel.loadSettings( thisElement, "inputcontroller" ); + m_outputControllerModel.loadSettings( thisElement, "outputcontroller" ); + m_fixedInputVelocityModel.loadSettings( thisElement, "fixedinputvelocity" ); + m_fixedOutputVelocityModel.loadSettings( thisElement, "fixedoutputvelocity" ); + m_outputProgramModel.loadSettings( thisElement, "outputprogram" ); + m_readableModel.loadSettings( thisElement, "readable" ); + m_writableModel.loadSettings( thisElement, "writable" ); // restore connections - if( inputEnabled() ) + if( isInputEnabled() ) { - QStringList rp = _this.attribute( "inports" ).split( ',' ); - for( Map::ConstIterator it = m_readablePorts.begin(); - it != m_readablePorts.end(); ++it ) + QStringList rp = thisElement.attribute( "inports" ).split( ',' ); + for( Map::ConstIterator it = m_readablePorts.begin(); it != m_readablePorts.end(); ++it ) { if( it.value() != ( rp.indexOf( it.key() ) != -1 ) ) { @@ -273,11 +250,10 @@ void MidiPort::loadSettings( const QDomElement & _this ) emit readablePortsChanged(); } - if( outputEnabled() ) + if( isOutputEnabled() ) { - QStringList wp = _this.attribute( "outports" ).split( ',' ); - for( Map::ConstIterator it = m_writablePorts.begin(); - it != m_writablePorts.end(); ++it ) + QStringList wp = thisElement.attribute( "outports" ).split( ',' ); + for( Map::ConstIterator it = m_writablePorts.begin(); it != m_writablePorts.end(); ++it ) { if( it.value() != ( wp.indexOf( it.key() ) != -1 ) ) { @@ -291,35 +267,38 @@ void MidiPort::loadSettings( const QDomElement & _this ) -void MidiPort::subscribeReadablePort( const QString & _port, bool _subscribe ) +void MidiPort::subscribeReadablePort( const QString& port, bool subscribe ) { - m_readablePorts[_port] = _subscribe; + m_readablePorts[port] = subscribe; + // make sure, MIDI-port is configured for input - if( _subscribe == true && !inputEnabled() ) + if( subscribe == true && !isInputEnabled() ) { m_readableModel.setValue( true ); } - m_midiClient->subscribeReadablePort( this, _port, _subscribe ); + + m_midiClient->subscribeReadablePort( this, port, subscribe ); } -void MidiPort::subscribeWritablePort( const QString & _port, bool _subscribe ) +void MidiPort::subscribeWritablePort( const QString& port, bool subscribe ) { - m_writablePorts[_port] = _subscribe; + m_writablePorts[port] = subscribe; + // make sure, MIDI-port is configured for output - if( _subscribe == true && !outputEnabled() ) + if( subscribe == true && !isOutputEnabled() ) { m_writableModel.setValue( true ); } - m_midiClient->subscribeWritablePort( this, _port, _subscribe ); + m_midiClient->subscribeWritablePort( this, port, subscribe ); } -void MidiPort::updateMidiPortMode( void ) +void MidiPort::updateMidiPortMode() { // this small lookup-table makes everything easier static const Modes modeTable[2][2] = @@ -330,10 +309,9 @@ void MidiPort::updateMidiPortMode( void ) setMode( modeTable[m_readableModel.value()][m_writableModel.value()] ); // check whether we have to dis-check items in connection-menu - if( !inputEnabled() ) + if( !isInputEnabled() ) { - for( Map::ConstIterator it = m_readablePorts.begin(); - it != m_readablePorts.end(); ++it ) + for( Map::ConstIterator it = m_readablePorts.begin(); it != m_readablePorts.end(); ++it ) { // subscribed? if( it.value() ) @@ -343,10 +321,9 @@ void MidiPort::updateMidiPortMode( void ) } } - if( !outputEnabled() ) + if( !isOutputEnabled() ) { - for( Map::ConstIterator it = m_writablePorts.begin(); - it != m_writablePorts.end(); ++it ) + for( Map::ConstIterator it = m_writablePorts.begin(); it != m_writablePorts.end(); ++it ) { // subscribed? if( it.value() ) @@ -366,42 +343,41 @@ void MidiPort::updateMidiPortMode( void ) -void MidiPort::updateReadablePorts( void ) +void MidiPort::updateReadablePorts() { // first save all selected ports - QStringList selected_ports; - for( Map::ConstIterator it = m_readablePorts.begin(); - it != m_readablePorts.end(); ++it ) + QStringList selectedPorts; + for( Map::ConstIterator it = m_readablePorts.begin(); it != m_readablePorts.end(); ++it ) { - if( it.value() == true ) + if( it.value() ) { - selected_ports.push_back( it.key() ); + selectedPorts.push_back( it.key() ); } } m_readablePorts.clear(); - const QStringList & wp = m_midiClient->readablePorts(); + const QStringList& wp = m_midiClient->readablePorts(); // now insert new ports and restore selections for( QStringList::ConstIterator it = wp.begin(); it != wp.end(); ++it ) { - m_readablePorts[*it] = ( selected_ports.indexOf( *it ) != -1 ); + m_readablePorts[*it] = ( selectedPorts.indexOf( *it ) != -1 ); } + emit readablePortsChanged(); } -void MidiPort::updateWritablePorts( void ) +void MidiPort::updateWritablePorts() { // first save all selected ports - QStringList selected_ports; - for( Map::ConstIterator it = m_writablePorts.begin(); - it != m_writablePorts.end(); ++it ) + QStringList selectedPorts; + for( Map::ConstIterator it = m_writablePorts.begin(); it != m_writablePorts.end(); ++it ) { - if( it.value() == true ) + if( it.value() ) { - selected_ports.push_back( it.key() ); + selectedPorts.push_back( it.key() ); } } @@ -410,19 +386,18 @@ void MidiPort::updateWritablePorts( void ) // now insert new ports and restore selections for( QStringList::ConstIterator it = wp.begin(); it != wp.end(); ++it ) { - m_writablePorts[*it] = ( selected_ports.indexOf( *it ) != -1 ); + m_writablePorts[*it] = ( selectedPorts.indexOf( *it ) != -1 ); } + emit writablePortsChanged(); } -void MidiPort::updateOutputProgram( void ) +void MidiPort::updateOutputProgram() { - processOutEvent( midiEvent( MidiProgramChange, - realOutputChannel(), - outputProgram()-1 ), midiTime( 0 ) ); + processOutEvent( MidiEvent( MidiProgramChange, realOutputChannel(), outputProgram()-1 ) ); } diff --git a/src/core/midi/MidiWinMM.cpp b/src/core/midi/MidiWinMM.cpp index dc06db8913..799d7f5df1 100644 --- a/src/core/midi/MidiWinMM.cpp +++ b/src/core/midi/MidiWinMM.cpp @@ -1,7 +1,7 @@ /* * MidiWinMM.cpp - WinMM MIDI client * - * Copyright (c) 2008-2009 Tobias Doerffel + * Copyright (c) 2008-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -57,33 +57,28 @@ MidiWinMM::~MidiWinMM() -void MidiWinMM::processOutEvent( const midiEvent & _me, - const midiTime & _time, - const MidiPort * _port ) +void MidiWinMM::processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port ) { - const DWORD shortMsg = ( _me.m_type + _me.channel() ) + - ( ( _me.m_data.m_param[0] & 0xff ) << 8 ) + - ( ( _me.m_data.m_param[1] & 0xff ) << 16 ); + const DWORD shortMsg = ( event.type() + event.channel() ) + + ( ( event.param( 0 ) & 0xff ) << 8 ) + + ( ( event.param( 1 ) & 0xff ) << 16 ); - QStringList out_devs; - for( SubMap::ConstIterator it = m_outputSubs.begin(); - it != m_outputSubs.end(); ++it ) + QStringList outDevs; + for( SubMap::ConstIterator it = m_outputSubs.begin(); it != m_outputSubs.end(); ++it ) { - for( MidiPortList::ConstIterator jt = it.value().begin(); - jt != it.value().end(); ++jt ) + for( MidiPortList::ConstIterator jt = it.value().begin(); jt != it.value().end(); ++jt ) { - if( *jt == _port ) + if( *jt == port ) { - out_devs += it.key(); + outDevs += it.key(); break; } } } - for( QMap::Iterator it = m_outputDevices.begin(); - it != m_outputDevices.end(); ++it ) + for( QMap::Iterator it = m_outputDevices.begin(); it != m_outputDevices.end(); ++it ) { - if( out_devs.contains( *it ) ) + if( outDevs.contains( *it ) ) { midiOutShortMsg( it.key(), shortMsg ); } @@ -93,25 +88,23 @@ void MidiWinMM::processOutEvent( const midiEvent & _me, -void MidiWinMM::applyPortMode( MidiPort * _port ) +void MidiWinMM::applyPortMode( MidiPort* port ) { // make sure no subscriptions exist which are not possible with // current port-mode - if( !_port->inputEnabled() ) + if( !port->isInputEnabled() ) { - for( SubMap::Iterator it = m_inputSubs.begin(); - it != m_inputSubs.end(); ++it ) + for( SubMap::Iterator it = m_inputSubs.begin(); it != m_inputSubs.end(); ++it ) { - it.value().removeAll( _port ); + it.value().removeAll( port ); } } - if( !_port->outputEnabled() ) + if( !port->isOutputEnabled() ) { - for( SubMap::Iterator it = m_outputSubs.begin(); - it != m_outputSubs.end(); ++it ) + for( SubMap::Iterator it = m_outputSubs.begin(); it != m_outputSubs.end(); ++it ) { - it.value().removeAll( _port ); + it.value().removeAll( port ); } } } @@ -119,105 +112,97 @@ void MidiWinMM::applyPortMode( MidiPort * _port ) -void MidiWinMM::removePort( MidiPort * _port ) +void MidiWinMM::removePort( MidiPort* port ) { - for( SubMap::Iterator it = m_inputSubs.begin(); - it != m_inputSubs.end(); ++it ) + for( SubMap::Iterator it = m_inputSubs.begin(); it != m_inputSubs.end(); ++it ) { - it.value().removeAll( _port ); + it.value().removeAll( port ); } - for( SubMap::Iterator it = m_outputSubs.begin(); - it != m_outputSubs.end(); ++it ) + + for( SubMap::Iterator it = m_outputSubs.begin(); it != m_outputSubs.end(); ++it ) { - it.value().removeAll( _port ); + it.value().removeAll( port ); } - MidiClient::removePort( _port ); + + MidiClient::removePort( port ); } -QString MidiWinMM::sourcePortName( const midiEvent & _event ) const +QString MidiWinMM::sourcePortName( const MidiEvent& event ) const { - if( _event.sourcePort() ) + if( event.sourcePort() ) { - return m_inputDevices.value( *static_cast( - _event.sourcePort() ) ); + return m_inputDevices.value( *static_cast( event.sourcePort() ) ); } - return MidiClient::sourcePortName( _event ); + + return MidiClient::sourcePortName( event ); } -void MidiWinMM::subscribeReadablePort( MidiPort * _port, - const QString & _dest, - bool _subscribe ) +void MidiWinMM::subscribeReadablePort( MidiPort* port, const QString& dest, bool subscribe ) { - if( _subscribe && _port->inputEnabled() == false ) + if( subscribe && port->isInputEnabled() == false ) { - qWarning( "port %s can't be (un)subscribed!\n", - _port->displayName().toAscii().constData() ); + qWarning( "port %s can't be (un)subscribed!\n", port->displayName().toAscii().constData() ); return; } - m_inputSubs[_dest].removeAll( _port ); - if( _subscribe ) + m_inputSubs[dest].removeAll( port ); + if( subscribe ) { - m_inputSubs[_dest].push_back( _port ); + m_inputSubs[dest].push_back( port ); } } -void MidiWinMM::subscribeWritablePort( MidiPort * _port, - const QString & _dest, - bool _subscribe ) +void MidiWinMM::subscribeWritablePort( MidiPort* port, const QString& dest, bool subscribe ) { - if( _subscribe && _port->outputEnabled() == false ) + if( subscribe && port->isOutputEnabled() == false ) { - qWarning( "port %s can't be (un)subscribed!\n", - _port->displayName().toAscii().constData() ); + qWarning( "port %s can't be (un)subscribed!\n", port->displayName().toAscii().constData() ); return; } - m_outputSubs[_dest].removeAll( _port ); - if( _subscribe ) + m_outputSubs[dest].removeAll( port ); + if( subscribe ) { - m_outputSubs[_dest].push_back( _port ); + m_outputSubs[dest].push_back( port ); } } -void WINAPI CALLBACK MidiWinMM::inputCallback( HMIDIIN _hm, UINT _msg, DWORD_PTR _inst, - DWORD_PTR _param1, DWORD_PTR _param2 ) +void WINAPI CALLBACK MidiWinMM::inputCallback( HMIDIIN hm, UINT msg, DWORD_PTR inst, DWORD_PTR param1, DWORD_PTR param2 ) { - if( _msg == MIM_DATA ) + if( msg == MIM_DATA ) { - ( (MidiWinMM *) _inst )->handleInputEvent( _hm, _param1 ); + ( (MidiWinMM *) inst )->handleInputEvent( hm, param1 ); } } -void MidiWinMM::handleInputEvent( HMIDIIN _hm, DWORD _ev ) +void MidiWinMM::handleInputEvent( HMIDIIN hm, DWORD ev ) { - const int cmd = _ev & 0xff; + const int cmd = ev & 0xff; if( cmd == MidiActiveSensing ) { return; } - const int par1 = ( _ev >> 8 ) & 0xff; - const int par2 = _ev >> 16; - const MidiEventTypes cmdtype = - static_cast( cmd & 0xf0 ); + const int par1 = ( ev >> 8 ) & 0xff; + const int par2 = ev >> 16; + const MidiEventTypes cmdtype = static_cast( cmd & 0xf0 ); const int chan = cmd & 0x0f; - const QString d = m_inputDevices.value( _hm ); + const QString d = m_inputDevices.value( hm ); if( d.isEmpty() || !m_inputSubs.contains( d ) ) { return; @@ -231,28 +216,21 @@ void MidiWinMM::handleInputEvent( HMIDIIN _hm, DWORD _ev ) case MidiNoteOn: case MidiNoteOff: case MidiKeyPressure: - ( *it )->processInEvent( - midiEvent( cmdtype, chan, par1 - KeysPerOctave, - par2 & 0xff, &_hm ), midiTime() ); + ( *it )->processInEvent( MidiEvent( cmdtype, chan, par1 - KeysPerOctave, par2 & 0xff, &hm ) ); break; case MidiControlChange: case MidiProgramChange: case MidiChannelPressure: - ( *it )->processInEvent( - midiEvent( cmdtype, chan, par1, par2 & 0xff, &_hm ), - midiTime() ); + ( *it )->processInEvent( MidiEvent( cmdtype, chan, par1, par2 & 0xff, &hm ) ); break; case MidiPitchBend: - ( *it )->processInEvent( - midiEvent( cmdtype, chan, par1 + par2*128, 0, &_hm ), - midiTime() ); + ( *it )->processInEvent( MidiEvent( cmdtype, chan, par1 + par2*128, 0, &hm ) ); break; default: - qWarning( "WinMM-MIDI: unhandled input " - "event %d\n", cmdtype ); + qWarning( "MidiWinMM: unhandled input event %d\n", cmdtype ); break; } } @@ -265,17 +243,9 @@ void MidiWinMM::updateDeviceList() { closeDevices(); openDevices(); -// if( m_readablePorts != readable_ports ) - { -// m_readablePorts = readable_ports; - emit readablePortsChanged(); - } -// if( m_writablePorts != writable_ports ) - { -// m_writablePorts = writable_ports; - emit writablePortsChanged(); - } + emit readablePortsChanged(); + emit writablePortsChanged(); } @@ -339,8 +309,8 @@ void MidiWinMM::openDevices() -MidiWinMM::setupWidget::setupWidget( QWidget * _parent ) : - MidiClient::setupWidget( MidiWinMM::name(), _parent ) +MidiWinMM::setupWidget::setupWidget( QWidget* parent ) : + MidiClient::setupWidget( MidiWinMM::name(), parent ) { } diff --git a/src/core/note.cpp b/src/core/note.cpp index 2d77f02373..ce86cb9c04 100644 --- a/src/core/note.cpp +++ b/src/core/note.cpp @@ -35,7 +35,7 @@ -note::note( const midiTime & _length, const midiTime & _pos, +note::note( const MidiTime & _length, const MidiTime & _pos, int _key, volume_t _volume, panning_t _panning, DetuningHelper * _detuning ) : m_selected( false ), @@ -96,7 +96,7 @@ note::~note() -void note::setLength( const midiTime & _length ) +void note::setLength( const MidiTime & _length ) { // addJournalEntry( journalEntry( ChangeLength, m_length - _length ) ); m_length = _length; @@ -105,7 +105,7 @@ void note::setLength( const midiTime & _length ) -void note::setPos( const midiTime & _pos ) +void note::setPos( const MidiTime & _pos ) { // addJournalEntry( journalEntry( ChangePosition, m_pos - _pos ) ); m_pos = _pos; @@ -144,7 +144,7 @@ void note::setPanning( const panning_t _panning ) -midiTime note::quantized( const midiTime & _m, const int _q_grid ) +MidiTime note::quantized( const MidiTime & _m, const int _q_grid ) { float p = ( (float) _m / _q_grid ); if( p - floorf( p ) < 0.5f ) diff --git a/src/core/note_play_handle.cpp b/src/core/note_play_handle.cpp index 88482599cf..16ce402fe3 100644 --- a/src/core/note_play_handle.cpp +++ b/src/core/note_play_handle.cpp @@ -29,6 +29,7 @@ #include "DetuningHelper.h" #include "InstrumentSoundShaping.h" #include "InstrumentTrack.h" +#include "MidiEvent.h" #include "MidiPort.h" #include "song.h" @@ -48,7 +49,9 @@ notePlayHandle::notePlayHandle( InstrumentTrack * _it, const f_cnt_t _frames, const note & _n, notePlayHandle *parent, - const bool _part_of_arp ) : + const bool _part_of_arp, + int midiEventChannel, + Origin origin ) : playHandle( NotePlayHandle, _offset ), note( _n.length(), _n.pos(), _n.key(), _n.getVolume(), _n.getPanning(), _n.detuning() ), @@ -73,7 +76,9 @@ notePlayHandle::notePlayHandle( InstrumentTrack * _it, m_frequency( 0 ), m_unpitchedFrequency( 0 ), m_baseDetuning( NULL ), - m_songGlobalParentOffset( 0 ) + m_songGlobalParentOffset( 0 ), + m_midiChannel( midiEventChannel >= 0 ? midiEventChannel : instrumentTrack()->midiPort()->realOutputChannel() ), + m_origin( origin ) { if( isTopNote() ) { @@ -100,15 +105,18 @@ notePlayHandle::notePlayHandle( InstrumentTrack * _it, setFrames( _frames ); + // inform attached components about new MIDI note (used for recording in Piano Roll) + if( m_origin == OriginMidiInput ) + { + m_instrumentTrack->midiNoteOn( *this ); + } if( !isTopNote() || !instrumentTrack()->isArpeggioEnabled() ) { - // send MIDI-note-on-event - m_instrumentTrack->processOutEvent( midiEvent( MidiNoteOn, - m_instrumentTrack->midiPort()->realOutputChannel(), - midiKey(), midiVelocity() ), - midiTime::fromFrames( offset(), - engine::framesPerTick() ) ); + // send MidiNoteOn event + m_instrumentTrack->processOutEvent( + MidiEvent( MidiNoteOn, midiChannel(), midiKey(), midiVelocity() ), + MidiTime::fromFrames( offset(), engine::framesPerTick() ) ); } } @@ -119,6 +127,13 @@ notePlayHandle::~notePlayHandle() { noteOff( 0 ); + // inform attached components about MIDI finished (used for recording in Piano Roll) + if( m_origin == OriginMidiInput ) + { + setLength( MidiTime( static_cast( totalFramesPlayed() / engine::framesPerTick() ) ) ); + m_instrumentTrack->midiNoteOff( *this ); + } + if( isTopNote() ) { delete m_baseDetuning; @@ -151,10 +166,21 @@ notePlayHandle::~notePlayHandle() void notePlayHandle::setVolume( const volume_t _volume ) { note::setVolume( _volume ); - m_instrumentTrack->processOutEvent( midiEvent( MidiKeyPressure, - m_instrumentTrack->midiPort()->realOutputChannel(), - midiKey(), midiVelocity() ), 0 ); - + + m_instrumentTrack->processOutEvent( MidiEvent( MidiKeyPressure, midiChannel(), midiKey(), midiVelocity() ) ); +} + + + + +void notePlayHandle::setPanning( const panning_t panning ) +{ + note::setPanning( panning ); + + MidiEvent event( MidiMetaEvent, midiChannel(), midiKey(), panningToMidi( panning ) ); + event.setMetaEvent( MidiNotePanning ); + + m_instrumentTrack->processOutEvent( event ); } @@ -279,9 +305,10 @@ void notePlayHandle::play( sampleFrame * _working_buffer ) // can set m_releaseFramesDone to m_releaseFramesToDo so that // notePlayHandle::done() returns true and also this base-note is // removed from mixer's active note vector - if( isArpeggioBaseNote() && m_subNotes.size() == 0 ) + if( m_released && isArpeggioBaseNote() && m_subNotes.size() == 0 ) { m_releaseFramesDone = m_releaseFramesToDo; + m_frames = 0; } // update internal data @@ -341,12 +368,10 @@ void notePlayHandle::noteOff( const f_cnt_t _s ) if( !isTopNote() || !instrumentTrack()->isArpeggioEnabled() ) { - // send MIDI-note-off-event - m_instrumentTrack->processOutEvent( midiEvent( MidiNoteOff, - m_instrumentTrack->midiPort()->realOutputChannel(), - midiKey(), 0 ), - midiTime::fromFrames( m_framesBeforeRelease, - engine::framesPerTick() ) ); + // send MidiNoteOff event + m_instrumentTrack->processOutEvent( + MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ), + MidiTime::fromFrames( m_framesBeforeRelease, engine::framesPerTick() ) ); } m_released = true; @@ -501,7 +526,7 @@ void notePlayHandle::updateFrequency() -void notePlayHandle::processMidiTime( const midiTime& time ) +void notePlayHandle::processMidiTime( const MidiTime& time ) { if( detuning() && time >= songGlobalParentOffset()+pos() ) { diff --git a/src/core/preset_preview_play_handle.cpp b/src/core/preset_preview_play_handle.cpp index 09139ba216..22ff31a50d 100644 --- a/src/core/preset_preview_play_handle.cpp +++ b/src/core/preset_preview_play_handle.cpp @@ -89,12 +89,24 @@ public: m_dataMutex.unlock(); } + bool isPreviewing() + { + bool ret = m_dataMutex.tryLock(); + if( ret == true ) + { + m_dataMutex.unlock(); + } + return ret; + } + private: InstrumentTrack * m_previewInstrumentTrack; notePlayHandle * m_previewNote; QMutex m_dataMutex; + friend class presetPreviewPlayHandle; + } ; @@ -242,3 +254,17 @@ ConstNotePlayHandleList presetPreviewPlayHandle::nphsOfInstrumentTrack( } + + +bool presetPreviewPlayHandle::isPreviewing() +{ + bool ret = s_previewTC->m_dataMutex.tryLock(); + if( ret == true ) + { + s_previewTC->m_dataMutex.unlock(); + } + return ret; +} + + + diff --git a/src/core/song.cpp b/src/core/song.cpp index a32f453d73..f01e7f0cdb 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -76,7 +76,7 @@ #include #endif -tick_t midiTime::s_ticksPerTact = DefaultTicksPerTact; +tick_t MidiTime::s_ticksPerTact = DefaultTicksPerTact; @@ -201,7 +201,7 @@ song::~song() } if( m_SncVSTplug != NULL ) { - delete m_SncVSTplug; + free( m_SncVSTplug ); m_SncVSTplug = NULL; } } @@ -256,7 +256,7 @@ void song::setTempo() void song::setTimeSignature() { - midiTime::setTicksPerTact( ticksPerTact() ); + MidiTime::setTicksPerTact( ticksPerTact() ); emit timeSignatureChanged( m_oldTicksPerTact, ticksPerTact() ); emit dataChanged(); m_oldTicksPerTact = ticksPerTact(); @@ -494,7 +494,7 @@ void song::processNextBuffer() #endif // did we play a whole tact? - if( ticks >= midiTime::ticksPerTact() ) + if( ticks >= MidiTime::ticksPerTact() ) { // per default we just continue playing even if // there's no more stuff to play @@ -525,7 +525,7 @@ void song::processNextBuffer() // then start from beginning and keep // offset ticks = ticks % ( max_tact * - midiTime::ticksPerTact() ); + MidiTime::ticksPerTact() ); #ifdef VST_SNC_LATENCY m_SncVSTplug->ppqPos = ( ( ticks + 0 ) / (float)48 ) diff --git a/src/core/timeline.cpp b/src/core/timeline.cpp index 74d754eba0..3c0aa6f11e 100644 --- a/src/core/timeline.cpp +++ b/src/core/timeline.cpp @@ -47,7 +47,7 @@ QPixmap * timeLine::s_loopPointPixmap = NULL; timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt, - song::playPos & _pos, const midiTime & _begin, + song::playPos & _pos, const MidiTime & _begin, QWidget * _parent ) : QWidget( _parent ), m_autoScroll( AutoScrollEnabled ), @@ -175,7 +175,7 @@ void timeLine::loadSettings( const QDomElement & _this ) -void timeLine::updatePosition( const midiTime & ) +void timeLine::updatePosition( const MidiTime & ) { const int new_x = markerX( m_pos ); @@ -238,7 +238,7 @@ void timeLine::paintEvent( QPaintEvent * ) tact_t tact_num = m_begin.getTact(); int x = m_xOffset + s_posMarkerPixmap->width() / 2 - - ( ( static_cast( m_begin * m_ppt ) / midiTime::ticksPerTact() ) % static_cast( m_ppt ) ); + ( ( static_cast( m_begin * m_ppt ) / MidiTime::ticksPerTact() ) % static_cast( m_ppt ) ); p.setPen( QColor( 192, 192, 192 ) ); for( int i = 0; x + i * m_ppt < width(); ++i ) @@ -248,7 +248,7 @@ void timeLine::paintEvent( QPaintEvent * ) ++tact_num; if( ( tact_num - 1 ) % qMax( 1, qRound( 1.0f / 3.0f * - midiTime::ticksPerTact() / m_ppt ) ) == 0 ) + MidiTime::ticksPerTact() / m_ppt ) ) == 0 ) { const QString s = QString::number( tact_num ); p.drawText( cx + qRound( ( m_ppt - p.fontMetrics(). @@ -285,7 +285,7 @@ void timeLine::mousePressEvent( QMouseEvent* event ) } else if( event->button() == Qt::RightButton ) { - const midiTime t = m_begin + static_cast( event->x() * midiTime::ticksPerTact() / m_ppt ); + const MidiTime t = m_begin + static_cast( event->x() * MidiTime::ticksPerTact() / m_ppt ); if( m_loopPos[0] > m_loopPos[1] ) { qSwap( m_loopPos[0], m_loopPos[1] ); @@ -324,7 +324,7 @@ void timeLine::mousePressEvent( QMouseEvent* event ) void timeLine::mouseMoveEvent( QMouseEvent* event ) { - const midiTime t = m_begin + static_cast( qMax( event->x() - m_xOffset - m_moveXOff, 0 ) * midiTime::ticksPerTact() / m_ppt ); + const MidiTime t = m_begin + static_cast( qMax( event->x() - m_xOffset - m_moveXOff, 0 ) * MidiTime::ticksPerTact() / m_ppt ); switch( m_action ) { @@ -356,9 +356,9 @@ void timeLine::mouseMoveEvent( QMouseEvent* event ) // Note, swap 1 and 0 below and the behavior "skips" the other // marking instead of pushing it. if( m_action == MoveLoopBegin ) - m_loopPos[0] -= midiTime::ticksPerTact(); + m_loopPos[0] -= MidiTime::ticksPerTact(); else - m_loopPos[1] += midiTime::ticksPerTact(); + m_loopPos[1] += MidiTime::ticksPerTact(); } update(); break; diff --git a/src/core/track.cpp b/src/core/track.cpp index 10a4ed80fb..f11210e270 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -145,7 +145,7 @@ trackContentObject::~trackContentObject() * * \param _pos The new position of the track content object. */ -void trackContentObject::movePosition( const midiTime & _pos ) +void trackContentObject::movePosition( const MidiTime & _pos ) { if( m_startPosition != _pos ) { @@ -166,7 +166,7 @@ void trackContentObject::movePosition( const midiTime & _pos ) * * \param _length The new length of the track content object. */ -void trackContentObject::changeLength( const midiTime & _length ) +void trackContentObject::changeLength( const MidiTime & _length ) { if( m_length != _length ) { @@ -243,7 +243,7 @@ void trackContentObject::paste() { if( Clipboard::getContent( nodeName() ) != NULL ) { - const midiTime pos = startPosition(); + const MidiTime pos = startPosition(); restoreState( *( Clipboard::getContent( nodeName() ) ) ); movePosition( pos ); } @@ -422,7 +422,7 @@ void trackContentObjectView::updateLength() { setFixedWidth( static_cast( m_tco->length() * pixelsPerTact() / - midiTime::ticksPerTact() ) + + MidiTime::ticksPerTact() ) + TCO_BORDER_WIDTH * 2-1 ); } m_trackView->trackContainerView()->update(); @@ -485,7 +485,7 @@ void trackContentObjectView::dropEvent( QDropEvent * _de ) multimediaProject mmp( value.toUtf8() ); // at least save position before getting to moved to somewhere // the user doesn't expect... - midiTime pos = m_tco->startPosition(); + MidiTime pos = m_tco->startPosition(); m_tco->restoreState( mmp.content().firstChild().toElement() ); m_tco->movePosition( pos ); AutomationPattern::resolveAllIDs(); @@ -654,9 +654,9 @@ void trackContentObjectView::mouseMoveEvent( QMouseEvent * _me ) if( m_action == Move ) { const int x = mapToParent( _me->pos() ).x() - m_initialMouseX; - midiTime t = qMax( 0, (int) + MidiTime t = qMax( 0, (int) m_trackView->trackContainerView()->currentPosition()+ - static_cast( x * midiTime::ticksPerTact() / + static_cast( x * MidiTime::ticksPerTact() / ppt ) ); if( ! ( _me->modifiers() & Qt::ControlModifier ) && _me->button() == Qt::NoButton ) @@ -668,7 +668,7 @@ void trackContentObjectView::mouseMoveEvent( QMouseEvent * _me ) s_textFloat->setText( QString( "%1:%2" ). arg( m_tco->startPosition().getTact() + 1 ). arg( m_tco->startPosition().getTicks() % - midiTime::ticksPerTact() ) ); + MidiTime::ticksPerTact() ) ); s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2 ) ); } @@ -678,7 +678,7 @@ void trackContentObjectView::mouseMoveEvent( QMouseEvent * _me ) QVector so = m_trackView->trackContainerView()->selectedObjects(); QVector tcos; - midiTime smallest_pos, t; + MidiTime smallest_pos, t; // find out smallest position of all selected objects for not // moving an object before zero for( QVector::iterator it = so.begin(); @@ -695,13 +695,13 @@ void trackContentObjectView::mouseMoveEvent( QMouseEvent * _me ) smallest_pos = qMin( smallest_pos, (int)tco->startPosition() + static_cast( dx * - midiTime::ticksPerTact() / ppt ) ); + MidiTime::ticksPerTact() / ppt ) ); } for( QVector::iterator it = tcos.begin(); it != tcos.end(); ++it ) { t = ( *it )->startPosition() + - static_cast( dx *midiTime::ticksPerTact() / + static_cast( dx *MidiTime::ticksPerTact() / ppt )-smallest_pos; if( ! ( _me->modifiers() & Qt::AltModifier ) && _me->button() == Qt::NoButton ) @@ -713,22 +713,22 @@ void trackContentObjectView::mouseMoveEvent( QMouseEvent * _me ) } else if( m_action == Resize ) { - midiTime t = qMax( midiTime::ticksPerTact() / 16, static_cast( _me->x() * midiTime::ticksPerTact() / ppt ) ); + MidiTime t = qMax( MidiTime::ticksPerTact() / 16, static_cast( _me->x() * MidiTime::ticksPerTact() / ppt ) ); if( ! ( _me->modifiers() & Qt::ControlModifier ) && _me->button() == Qt::NoButton ) { - t = qMax( midiTime::ticksPerTact(), t.toNearestTact() ); + t = qMax( MidiTime::ticksPerTact(), t.toNearestTact() ); } m_tco->changeLength( t ); s_textFloat->setText( tr( "%1:%2 (%3:%4 to %5:%6)" ). arg( m_tco->length().getTact() ). arg( m_tco->length().getTicks() % - midiTime::ticksPerTact() ). + MidiTime::ticksPerTact() ). arg( m_tco->startPosition().getTact() + 1 ). arg( m_tco->startPosition().getTicks() % - midiTime::ticksPerTact() ). + MidiTime::ticksPerTact() ). arg( m_tco->endPosition().getTact() + 1 ). arg( m_tco->endPosition().getTicks() % - midiTime::ticksPerTact() ) ); + MidiTime::ticksPerTact() ) ); s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2) ); } @@ -864,8 +864,8 @@ trackContentWidget::trackContentWidget( trackView * _parent ) : setAcceptDrops( true ); connect( _parent->trackContainerView(), - SIGNAL( positionChanged( const midiTime & ) ), - this, SLOT( changePosition( const midiTime & ) ) ); + SIGNAL( positionChanged( const MidiTime & ) ), + this, SLOT( changePosition( const MidiTime & ) ) ); updateBackground(); } @@ -1014,7 +1014,7 @@ void trackContentWidget::update() * * \param _new_pos The MIDI time to move to. */ -void trackContentWidget::changePosition( const midiTime & _new_pos ) +void trackContentWidget::changePosition( const MidiTime & _new_pos ) { if( m_trackView->trackContainerView() == engine::getBBEditor() ) { @@ -1051,7 +1051,7 @@ void trackContentWidget::changePosition( const midiTime & _new_pos ) return; } - midiTime pos = _new_pos; + MidiTime pos = _new_pos; if( pos < 0 ) { pos = m_trackView->trackContainerView()->currentPosition(); @@ -1077,7 +1077,7 @@ void trackContentWidget::changePosition( const midiTime & _new_pos ) ( ts <= begin && te >= end ) ) { tcov->move( static_cast( ( ts - begin ) * ppt / - midiTime::ticksPerTact() ), + MidiTime::ticksPerTact() ), tcov->y() ); if( !tcov->isVisible() ) { @@ -1122,7 +1122,7 @@ void trackContentWidget::dropEvent( QDropEvent * _de ) if( type == ( "tco_" + QString::number( getTrack()->type() ) ) && m_trackView->trackContainerView()->fixedTCOs() == false ) { - const midiTime pos = getPosition( _de->pos().x() + const MidiTime pos = getPosition( _de->pos().x() ).toNearestTact(); trackContentObject * tco = getTrack()->createTCO( pos ); @@ -1162,8 +1162,8 @@ void trackContentWidget::mousePressEvent( QMouseEvent * _me ) else if( _me->button() == Qt::LeftButton && !m_trackView->trackContainerView()->fixedTCOs() ) { - const midiTime pos = getPosition( _me->x() ).getTact() * - midiTime::ticksPerTact(); + const MidiTime pos = getPosition( _me->x() ).getTact() * + MidiTime::ticksPerTact(); trackContentObject * tco = getTrack()->createTCO( pos ); tco->saveJournallingState( false ); @@ -1237,7 +1237,7 @@ void trackContentWidget::undoStep( JournalEntry & _je ) case RemoveTrackContentObject: { - trackContentObject * tco = getTrack()->createTCO( midiTime( 0 ) ); + trackContentObject * tco = getTrack()->createTCO( MidiTime( 0 ) ); multimediaProject mmp( _je.data().toMap()["state"]. toString().toUtf8() ); @@ -1292,11 +1292,11 @@ track * trackContentWidget::getTrack() * * \param _mouse_x the mouse's current X position in pixels. */ -midiTime trackContentWidget::getPosition( int _mouse_x ) +MidiTime trackContentWidget::getPosition( int _mouse_x ) { - return midiTime( m_trackView->trackContainerView()-> + return MidiTime( m_trackView->trackContainerView()-> currentPosition() + _mouse_x * - midiTime::ticksPerTact() / + MidiTime::ticksPerTact() / static_cast( m_trackView-> trackContainerView()->pixelsPerTact() ) ); } @@ -1307,11 +1307,11 @@ midiTime trackContentWidget::getPosition( int _mouse_x ) * * \param _pos_start the starting position of the Widget (from getPosition()) */ -midiTime trackContentWidget::endPosition( const midiTime & _pos_start ) +MidiTime trackContentWidget::endPosition( const MidiTime & _pos_start ) { const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); const int w = width(); - return _pos_start + static_cast( w * midiTime::ticksPerTact() / ppt ); + return _pos_start + static_cast( w * MidiTime::ticksPerTact() / ppt ); } @@ -1762,7 +1762,7 @@ void track::loadSettings( const QDomElement & _this ) !node.toElement().attribute( "metadata" ).toInt() ) { trackContentObject * tco = createTCO( - midiTime( 0 ) ); + MidiTime( 0 ) ); tco->restoreState( node.toElement() ); saveJournallingState( false ); restoreJournallingState(); @@ -1852,7 +1852,7 @@ trackContentObject * track::getTCO( int _tco_num ) } printf( "called track::getTCO( %d ), " "but TCO %d doesn't exist\n", _tco_num, _tco_num ); - return createTCO( _tco_num * midiTime::ticksPerTact() ); + return createTCO( _tco_num * MidiTime::ticksPerTact() ); } @@ -1898,8 +1898,8 @@ int track::getTCONum( trackContentObject * _tco ) * \param _start The MIDI start time of the range. * \param _end The MIDI endi time of the range. */ -void track::getTCOsInRange( tcoVector & _tco_v, const midiTime & _start, - const midiTime & _end ) +void track::getTCOsInRange( tcoVector & _tco_v, const MidiTime & _start, + const MidiTime & _end ) { for( tcoVector::iterator it_o = m_trackContentObjects.begin(); it_o != m_trackContentObjects.end(); ++it_o ) @@ -1948,7 +1948,7 @@ void track::swapPositionOfTCOs( int _tco_num1, int _tco_num2 ) qSwap( m_trackContentObjects[_tco_num1], m_trackContentObjects[_tco_num2] ); - const midiTime pos = m_trackContentObjects[_tco_num1]->startPosition(); + const MidiTime pos = m_trackContentObjects[_tco_num1]->startPosition(); m_trackContentObjects[_tco_num1]->movePosition( m_trackContentObjects[_tco_num2]->startPosition() ); @@ -1965,7 +1965,7 @@ void track::swapPositionOfTCOs( int _tco_num1, int _tco_num2 ) * in ascending order by TCO time, once we hit a TCO that was earlier * than the insert time, we could fall out of the loop early. */ -void track::insertTact( const midiTime & _pos ) +void track::insertTact( const MidiTime & _pos ) { // we'll increase the position of every TCO, positioned behind _pos, by // one tact @@ -1975,7 +1975,7 @@ void track::insertTact( const midiTime & _pos ) if( ( *it )->startPosition() >= _pos ) { ( *it )->movePosition( (*it)->startPosition() + - midiTime::ticksPerTact() ); + MidiTime::ticksPerTact() ); } } } @@ -1987,7 +1987,7 @@ void track::insertTact( const midiTime & _pos ) * * \param _pos The time at which we want to remove the bar. */ -void track::removeTact( const midiTime & _pos ) +void track::removeTact( const MidiTime & _pos ) { // we'll decrease the position of every TCO, positioned behind _pos, by // one tact @@ -1997,7 +1997,7 @@ void track::removeTact( const midiTime & _pos ) if( ( *it )->startPosition() >= _pos ) { ( *it )->movePosition( qMax( ( *it )->startPosition() - - midiTime::ticksPerTact(), 0 ) ); + MidiTime::ticksPerTact(), 0 ) ); } } } @@ -2025,7 +2025,7 @@ tact_t track::length() const } } - return last / midiTime::ticksPerTact(); + return last / MidiTime::ticksPerTact(); } diff --git a/src/gui/AutomationEditor.cpp b/src/gui/AutomationEditor.cpp index ce3847f0e9..f7a25ec7b1 100644 --- a/src/gui/AutomationEditor.cpp +++ b/src/gui/AutomationEditor.cpp @@ -5,7 +5,7 @@ * Copyright (c) 2008-2014 Tobias Doerffel * Copyright (c) 2008-2013 Paul Giblock * Copyright (c) 2006-2008 Javier Serrano Polo - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -57,7 +57,6 @@ #include "gui_templates.h" #include "timeline.h" #include "tooltip.h" -#include "midi.h" #include "tool_button.h" #include "text_float.h" #include "combobox.h" @@ -131,10 +130,10 @@ AutomationEditor::AutomationEditor() : engine::getSong()->getPlayPos( song::Mode_PlayAutomationPattern ), m_currentPosition, this ); - connect( this, SIGNAL( positionChanged( const midiTime & ) ), - m_timeLine, SLOT( updatePosition( const midiTime & ) ) ); - connect( m_timeLine, SIGNAL( positionChanged( const midiTime & ) ), - this, SLOT( updatePosition( const midiTime & ) ) ); + connect( this, SIGNAL( positionChanged( const MidiTime & ) ), + m_timeLine, SLOT( updatePosition( const MidiTime & ) ) ); + connect( m_timeLine, SIGNAL( positionChanged( const MidiTime & ) ), + this, SLOT( updatePosition( const MidiTime & ) ) ); m_toolBar = new QWidget( this ); @@ -157,10 +156,14 @@ AutomationEditor::AutomationEditor() : tr( "Play/pause current pattern (Space)" ), this, SLOT( play() ), m_toolBar ); + m_stopButton = new toolButton( embed::getIconPixmap( "stop" ), tr( "Stop playing of current pattern (Space)" ), this, SLOT( stop() ), m_toolBar ); + m_playButton->setObjectName( "playButton" ); + m_stopButton->setObjectName( "stopButton" ); + m_playButton->setWhatsThis( tr( "Click here if you want to play the current pattern. " "This is useful while editing it. The pattern is " @@ -278,7 +281,7 @@ AutomationEditor::AutomationEditor() : connect( &m_tensionModel, SIGNAL( dataChanged() ), this, SLOT( tensionChanged() ) ); - + tool_button_group = new QButtonGroup( this ); tool_button_group->addButton( m_discreteButton ); tool_button_group->addButton( m_linearButton ); @@ -525,7 +528,7 @@ void AutomationEditor::updateAfterPatternChange() } if( m_pattern->progressionType() == - AutomationPattern::DiscreteProgression && + AutomationPattern::DiscreteProgression && !m_discreteButton->isChecked() ) { m_discreteButton->setChecked( true ); @@ -764,20 +767,20 @@ void AutomationEditor::drawLine( int _x0, float _y0, int _x1, float _y1 ) float yscale = deltay / ( deltax ); - if( _x0 < _x1) + if( _x0 < _x1) { xstep = quantization(); } - else + else { xstep = -( quantization() ); } if( _y0 < _y1 ) { - ystep = 1; + ystep = 1; } - else + else { ystep = -1; } @@ -789,8 +792,8 @@ void AutomationEditor::drawLine( int _x0, float _y0, int _x1, float _y1 ) x += xstep; i += 1; - m_pattern->removeValue( midiTime( x ) ); - m_pattern->putValue( midiTime( x ), y ); + m_pattern->removeValue( MidiTime( x ) ); + m_pattern->putValue( MidiTime( x ), y ); } } @@ -843,7 +846,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent * _me ) // loop through whole time-map... while( it != time_map.end() ) { - midiTime len = 4; + MidiTime len = 4; // and check whether the user clicked on an // existing value @@ -878,9 +881,9 @@ void AutomationEditor::mousePressEvent( QMouseEvent * _me ) if( it == time_map.end() ) { // then set new value - midiTime value_pos( pos_ticks ); - - midiTime new_time = + MidiTime value_pos( pos_ticks ); + + MidiTime new_time = m_pattern->putValue( value_pos, level ); @@ -1020,8 +1023,8 @@ void AutomationEditor::mouseMoveEvent( QMouseEvent * _me ) // moved properly according to new starting- // time in the time map of pattern m_pattern->removeValue( - midiTime( pos_ticks ) ); - m_pattern->putValue( midiTime( pos_ticks ), + MidiTime( pos_ticks ) ); + m_pattern->putValue( MidiTime( pos_ticks ), level ); } @@ -1033,7 +1036,7 @@ void AutomationEditor::mouseMoveEvent( QMouseEvent * _me ) ( _me->buttons() & Qt::LeftButton && m_editMode == ERASE ) ) { - m_pattern->removeValue( midiTime( pos_ticks ) ); + m_pattern->removeValue( MidiTime( pos_ticks ) ); } else if( _me->buttons() & Qt::NoButton && m_editMode == DRAW ) { @@ -1216,7 +1219,7 @@ void AutomationEditor::mouseMoveEvent( QMouseEvent * _me ) for( timeMap::iterator it = m_selValuesForMove.begin(); it != m_selValuesForMove.end(); ++it ) { - midiTime new_value_pos; + MidiTime new_value_pos; if( it.key() ) { int value_tact = @@ -1236,7 +1239,7 @@ void AutomationEditor::mouseMoveEvent( QMouseEvent * _me ) DefaultTicksPerTact; } m_pattern->removeValue( it.key() ); - new_value_pos = midiTime( value_tact, + new_value_pos = MidiTime( value_tact, value_ticks ); } new_selValuesForMove[ @@ -1578,7 +1581,7 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe ) is_selected ); } delete [] values; - + // Draw cross int y = yCoordOfLevel( it.value() ); p.drawLine( x - 1, y, x + 1, y ); @@ -1804,7 +1807,7 @@ void AutomationEditor::wheelEvent( QWheelEvent * _we ) m_timeLine->setPixelsPerTact( m_ppt ); update(); } - else if( _we->modifiers() & Qt::ShiftModifier + else if( _we->modifiers() & Qt::ShiftModifier || _we->orientation() == Qt::Horizontal ) { m_leftRightScroll->setValue( m_leftRightScroll->value() - @@ -2070,7 +2073,7 @@ void AutomationEditor::selectAll() const float level = it.value(); if( level < m_selectStartLevel ) { - // if we move start-level down, we have to add + // if we move start-level down, we have to add // the difference between old and new start-level // to m_selectedLevels, otherwise the selection // is just moved down... @@ -2242,7 +2245,7 @@ void AutomationEditor::deleteSelectedValues() -void AutomationEditor::updatePosition( const midiTime & _t ) +void AutomationEditor::updatePosition( const MidiTime & _t ) { if( ( engine::getSong()->isPlaying() && engine::getSong()->playMode() == @@ -2257,7 +2260,7 @@ void AutomationEditor::updatePosition( const midiTime & _t ) } else if( _t < m_currentPosition ) { - midiTime t = qMax( _t - w * DefaultTicksPerTact * + MidiTime t = qMax( _t - w * DefaultTicksPerTact * DefaultTicksPerTact / m_ppt, 0 ); m_leftRightScroll->setValue( t.getTact() * DefaultTicksPerTact ); diff --git a/src/gui/AutomationPatternView.cpp b/src/gui/AutomationPatternView.cpp index cd0127b367..e66c728b48 100644 --- a/src/gui/AutomationPatternView.cpp +++ b/src/gui/AutomationPatternView.cpp @@ -250,7 +250,7 @@ void AutomationPatternView::paintEvent( QPaintEvent * ) if( it+1 == m_pat->getTimeMap().end() ) { const float x1 = x_base + it.key() * ppt / - midiTime::ticksPerTact(); + MidiTime::ticksPerTact(); const float x2 = (float)( width() - TCO_BORDER_WIDTH ); p.fillRect( QRectF( x1, 0.0f, x2-x1, it.value() ), lin2grad ); @@ -262,9 +262,9 @@ void AutomationPatternView::paintEvent( QPaintEvent * ) { float value = values[i - it.key()]; const float x1 = x_base + i * ppt / - midiTime::ticksPerTact(); + MidiTime::ticksPerTact(); const float x2 = x_base + (i+1) * ppt / - midiTime::ticksPerTact(); + MidiTime::ticksPerTact(); p.fillRect( QRectF( x1, 0.0f, x2-x1, value ), lin2grad ); diff --git a/src/gui/ControllerConnectionDialog.cpp b/src/gui/ControllerConnectionDialog.cpp index 5e2903f683..66fed87d3f 100644 --- a/src/gui/ControllerConnectionDialog.cpp +++ b/src/gui/ControllerConnectionDialog.cpp @@ -63,13 +63,13 @@ public: } - virtual void processInEvent( const midiEvent& event, const midiTime& time ) + virtual void processInEvent( const MidiEvent& event, const MidiTime& time ) { - if( event.m_type == MidiControlChange && - ( m_midiPort.inputChannel() == event.m_channel + 1 || m_midiPort.inputChannel() == 0 ) ) + if( event.type() == MidiControlChange && + ( m_midiPort.inputChannel() == 0 || m_midiPort.inputChannel() == event.channel() + 1 ) ) { - m_detectedMidiChannel = event.m_channel + 1; - m_detectedMidiController = ( event.m_data.m_bytes[0] & 0x7F ) + 1; + m_detectedMidiChannel = event.channel() + 1; + m_detectedMidiController = event.controllerNumber() + 1; m_detectedMidiPort = engine::mixer()->midiClient()->sourcePortName( event ); emit valueChanged(); diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 02d5fb1783..2ff35c9a0d 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -209,6 +209,8 @@ FxMixerView::FxMixerView() : cv->m_rackView = new EffectRackView( &m->m_fxChannels[i]->m_fxChain, this ); + cv->m_rackView->setMinimumWidth( 244 ); + m_fxRacksLayout->addWidget( cv->m_rackView ); if( i == 0 ) { diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 682be6868d..c86975b3f3 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -275,7 +275,7 @@ void MainWindow::finalize( void ) QMenu * edit_menu = new QMenu( this ); menuBar()->addMenu( edit_menu )->setText( tr( "&Edit" ) ); - edit_menu->addAction( embed::getIconPixmap( "edit_undo" ), +/* edit_menu->addAction( embed::getIconPixmap( "edit_undo" ), tr( "Undo" ), this, SLOT( undo() ), Qt::CTRL + Qt::Key_Z ); @@ -283,7 +283,7 @@ void MainWindow::finalize( void ) tr( "Redo" ), this, SLOT( redo() ), Qt::CTRL + Qt::Key_R ); - edit_menu->addSeparator(); + edit_menu->addSeparator();*/ edit_menu->addAction( embed::getIconPixmap( "setup_general" ), tr( "Settings" ), this, SLOT( showSettingsDialog() ) ); @@ -412,7 +412,7 @@ void MainWindow::finalize( void ) toolButton * bb_editor_window = new toolButton( - embed::getIconPixmap( "bb_track" ), + embed::getIconPixmap( "bb_track_btn" ), tr( "Show/hide Beat+Bassline Editor" ) + " (F6)", this, SLOT( toggleBBEditorWin() ), diff --git a/src/gui/PianoView.cpp b/src/gui/PianoView.cpp index 18a916a1e4..021964b501 100644 --- a/src/gui/PianoView.cpp +++ b/src/gui/PianoView.cpp @@ -53,7 +53,7 @@ #include "knob.h" #include "string_pair_drag.h" #include "MainWindow.h" -#include "midi.h" +#include "MidiEvent.h" #include "templates.h" #include "update_event.h" @@ -465,7 +465,7 @@ void PianoView::mousePressEvent( QMouseEvent * _me ) velocity = MidiMaxVelocity; } // set note on - m_piano->midiEventProcessor()->processInEvent( midiEvent( MidiNoteOn, 0, key_num, velocity ), midiTime() ); + m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOn, 0, key_num, velocity ) ); m_piano->setKeyState( key_num, true ); m_lastKey = key_num; @@ -510,7 +510,7 @@ void PianoView::mouseReleaseEvent( QMouseEvent * ) { if( m_piano != NULL ) { - m_piano->midiEventProcessor()->processInEvent( midiEvent( MidiNoteOff, 0, m_lastKey, 0 ), midiTime() ); + m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOff, 0, m_lastKey, 0 ) ); m_piano->setKeyState( m_lastKey, false ); } @@ -571,7 +571,7 @@ void PianoView::mouseMoveEvent( QMouseEvent * _me ) { if( m_lastKey != -1 ) { - m_piano->midiEventProcessor()->processInEvent( midiEvent( MidiNoteOff, 0, m_lastKey, 0 ), midiTime() ); + m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOff, 0, m_lastKey, 0 ) ); m_piano->setKeyState( m_lastKey, false ); m_lastKey = -1; } @@ -579,7 +579,7 @@ void PianoView::mouseMoveEvent( QMouseEvent * _me ) { if( _me->pos().y() > PIANO_BASE ) { - m_piano->midiEventProcessor()->processInEvent( midiEvent( MidiNoteOn, 0, key_num, velocity ), midiTime() ); + m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOn, 0, key_num, velocity ) ); m_piano->setKeyState( key_num, true ); m_lastKey = key_num; } @@ -593,7 +593,7 @@ void PianoView::mouseMoveEvent( QMouseEvent * _me ) } else if( m_piano->isKeyPressed( key_num ) ) { - m_piano->midiEventProcessor()->processInEvent( midiEvent( MidiKeyPressure, 0, key_num, velocity ), midiTime() ); + m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiKeyPressure, 0, key_num, velocity ) ); } } @@ -690,7 +690,7 @@ void PianoView::focusOutEvent( QFocusEvent * ) // hang otherwise for( int i = 0; i < NumKeys; ++i ) { - m_piano->midiEventProcessor()->processInEvent( midiEvent( MidiNoteOff, 0, i, 0 ), midiTime() ); + m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOff, 0, i, 0 ) ); m_piano->setKeyState( i, false ); } update(); diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index 214d802a1e..11a91727dc 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -127,9 +127,9 @@ trackView * TrackContainerView::addTrackView( trackView * _tv ) m_trackViews.push_back( _tv ); m_scrollLayout->addWidget( _tv ); - connect( this, SIGNAL( positionChanged( const midiTime & ) ), + connect( this, SIGNAL( positionChanged( const MidiTime & ) ), _tv->getTrackContentWidget(), - SLOT( changePosition( const midiTime & ) ) ); + SLOT( changePosition( const MidiTime & ) ) ); realignTracks(); return( _tv ); } diff --git a/src/gui/about_dialog.cpp b/src/gui/about_dialog.cpp index cd9cca16cd..94b6fb2173 100644 --- a/src/gui/about_dialog.cpp +++ b/src/gui/about_dialog.cpp @@ -67,7 +67,7 @@ aboutDialog::aboutDialog() : { setupUi( this ); - iconLabel->setPixmap( embed::getIconPixmap( "icon" ) ); + iconLabel->setPixmap( embed::getIconPixmap( "icon", 64, 64 ) ); versionLabel->setText( versionLabel->text(). arg( LMMS_VERSION ). diff --git a/src/gui/bb_editor.cpp b/src/gui/bb_editor.cpp index a26094e805..ec6de90344 100644 --- a/src/gui/bb_editor.cpp +++ b/src/gui/bb_editor.cpp @@ -2,7 +2,7 @@ * bb_editor.cpp - basic main-window for editing of beats and basslines * * Copyright (c) 2004-2008 Tobias Doerffel - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -85,6 +85,9 @@ bbEditor::bbEditor( bbTrackContainer* tc ) : tr( "Stop playback of current beat/bassline (Space)" ), this, SLOT( stop() ), m_toolBar ); + m_playButton->setObjectName( "playButton" ); + m_stopButton->setObjectName( "stopButton" ); + toolButton * add_bb_track = new toolButton( embed::getIconPixmap( "add_bb_track" ), tr( "Add beat/bassline" ), diff --git a/src/gui/dialogs/FileDialog.cpp b/src/gui/dialogs/FileDialog.cpp index ba25bf80e9..ad77018cc9 100644 --- a/src/gui/dialogs/FileDialog.cpp +++ b/src/gui/dialogs/FileDialog.cpp @@ -59,7 +59,7 @@ FileDialog::FileDialog( QWidget *parent, const QString &caption, void FileDialog::clearSelection() { - static QListView *view = findChild(); + QListView *view = findChild(); Q_ASSERT( view ); view->clearSelection(); } diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp index 0c854808d1..4a9d8203eb 100644 --- a/src/gui/piano_roll.cpp +++ b/src/gui/piano_roll.cpp @@ -56,7 +56,7 @@ #include "gui_templates.h" #include "InstrumentTrack.h" #include "MainWindow.h" -#include "midi.h" +#include "MidiEvent.h" #include "mmp.h" #include "pattern.h" #include "Piano.h" @@ -162,7 +162,7 @@ pianoRoll::pianoRoll() : m_oldNotesEditHeight( 100 ), m_notesEditHeight( 100 ), m_ppt( DEFAULT_PR_PPT ), - m_lenOfNewNotes( midiTime( 0, DefaultTicksPerTact/4 ) ), + m_lenOfNewNotes( MidiTime( 0, DefaultTicksPerTact/4 ) ), m_lastNoteVolume( DefaultVolume ), m_lastNotePanning( DefaultPanning ), m_startKey( INITIAL_START_KEY ), @@ -283,21 +283,21 @@ pianoRoll::pianoRoll() : engine::getSong()->getPlayPos( song::Mode_PlayPattern ), m_currentPosition, this ); - connect( this, SIGNAL( positionChanged( const midiTime & ) ), - m_timeLine, SLOT( updatePosition( const midiTime & ) ) ); - connect( m_timeLine, SIGNAL( positionChanged( const midiTime & ) ), - this, SLOT( updatePosition( const midiTime & ) ) ); + connect( this, SIGNAL( positionChanged( const MidiTime & ) ), + m_timeLine, SLOT( updatePosition( const MidiTime & ) ) ); + connect( m_timeLine, SIGNAL( positionChanged( const MidiTime & ) ), + this, SLOT( updatePosition( const MidiTime & ) ) ); // update timeline when in record-accompany mode connect( engine::getSong()->getPlayPos( song::Mode_PlaySong ).m_timeLine, - SIGNAL( positionChanged( const midiTime & ) ), + SIGNAL( positionChanged( const MidiTime & ) ), this, - SLOT( updatePositionAccompany( const midiTime & ) ) ); + SLOT( updatePositionAccompany( const MidiTime & ) ) ); // TODO /* connect( engine::getSong()->getPlayPos( song::Mode_PlayBB ).m_timeLine, - SIGNAL( positionChanged( const midiTime & ) ), + SIGNAL( positionChanged( const MidiTime & ) ), this, - SLOT( updatePositionAccompany( const midiTime & ) ) );*/ + SLOT( updatePositionAccompany( const MidiTime & ) ) );*/ m_toolBar = new QWidget( this ); @@ -331,6 +331,11 @@ pianoRoll::pianoRoll() : m_stopButton = new toolButton( embed::getIconPixmap( "stop" ), tr( "Stop playing of current pattern (Space)" ), this, SLOT( stop() ), m_toolBar ); + + m_playButton->setObjectName( "playButton" ); + m_stopButton->setObjectName( "stopButton" ); + m_recordButton->setObjectName( "recordButton" ); + m_recordAccompanyButton->setObjectName( "recordAccompanyButton" ); m_playButton->setWhatsThis( tr( "Click here to play the current pattern. " @@ -765,15 +770,9 @@ void pianoRoll::setCurrentPattern( pattern * _new_pattern ) // of start-notes and so on...) resizeEvent( NULL ); - connect( m_pattern->instrumentTrack(), - SIGNAL( noteOn( const note & ) ), - this, SLOT( startRecordNote( const note & ) ) ); - connect( m_pattern->instrumentTrack(), - SIGNAL( noteOff( const note & ) ), - this, SLOT( finishRecordNote( const note & ) ) ); - connect( m_pattern->instrumentTrack()->pianoModel(), - SIGNAL( dataChanged() ), - this, SLOT( update() ) ); + connect( m_pattern->instrumentTrack(), SIGNAL( midiNoteOn( const note& ) ), this, SLOT( startRecordNote( const note& ) ) ); + connect( m_pattern->instrumentTrack(), SIGNAL( midiNoteOff( const note& ) ), this, SLOT( finishRecordNote( const note& ) ) ); + connect( m_pattern->instrumentTrack()->pianoModel(), SIGNAL( dataChanged() ), this, SLOT( update() ) ); setWindowTitle( tr( "Piano-Roll - %1" ).arg( m_pattern->name() ) ); @@ -927,7 +926,7 @@ inline void pianoRoll::drawDetuningInfo( QPainter & _p, note * _n, int _x, { break; } - int pos_x = _x + pos_ticks * m_ppt / midiTime::ticksPerTact(); + int pos_x = _x + pos_ticks * m_ppt / MidiTime::ticksPerTact(); const float level = it.value(); @@ -1522,7 +1521,7 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) x -= WHITE_KEY_WIDTH; // get tick in which the user clicked - int pos_ticks = x * midiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + m_currentPosition; @@ -1535,7 +1534,7 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) // loop through whole note-vector... for( int i = 0; i < notes.size(); ++i ) { - midiTime len = ( *it )->length(); + MidiTime len = ( *it )->length(); if( len < 0 ) { len = 4; @@ -1552,7 +1551,7 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) ( edit_note == true && pos_ticks <= ( *it )->pos() + NE_LINE_WIDTH * - midiTime::ticksPerTact() / + MidiTime::ticksPerTact() / m_ppt ) ) ) @@ -1593,8 +1592,8 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) // +32 to quanitize the note correctly when placing notes with // the mouse. We do this here instead of in note.quantized // because live notes should still be quantized at the half. - midiTime note_pos( pos_ticks - ( quantization() / 2 ) ); - midiTime note_len( newNoteLen() ); + MidiTime note_pos( pos_ticks - ( quantization() / 2 ) ); + MidiTime note_len( newNoteLen() ); note new_note( note_len, note_pos, key_num ); new_note.setSelected( true ); @@ -1701,8 +1700,8 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) // clicked at the "tail" of the note? - if( pos_ticks*m_ppt/midiTime::ticksPerTact() > - ( m_currentNote->pos() + m_currentNote->length() )*m_ppt/ midiTime::ticksPerTact() - RESIZE_AREA_WIDTH && + if( pos_ticks*m_ppt/MidiTime::ticksPerTact() > + ( m_currentNote->pos() + m_currentNote->length() )*m_ppt/ MidiTime::ticksPerTact() - RESIZE_AREA_WIDTH && m_currentNote->length() > 0 ) { // then resize the note @@ -1865,16 +1864,16 @@ void pianoRoll::testPlayNote( note * n ) { m_lastKey = n->key(); - if( ! n->isPlaying() && ! m_recording && - ! engine::getSong()->isPlaying() ) + if( ! n->isPlaying() && ! m_recording && ! engine::getSong()->isPlaying() ) { n->setIsPlaying( true ); m_pattern->instrumentTrack()->pianoModel()->handleKeyPress( n->key(), volumeToMidi( n->getVolume() ) ); - midiEvent evt( MidiMetaEvent, 0, n->key(), panningToMidi( n->getPanning() ) ); - - evt.m_metaEvent = MidiNotePanning; - m_pattern->instrumentTrack()->processInEvent( evt, midiTime() ); + MidiEvent event( MidiMetaEvent, 0, n->key(), panningToMidi( n->getPanning() ) ); + + event.setMetaEvent( MidiNotePanning ); + + m_pattern->instrumentTrack()->processInEvent( event, 0 ); } } @@ -1919,10 +1918,6 @@ void pianoRoll::testPlayKey( int key, int velocity, int pan ) // play new key m_pattern->instrumentTrack()->pianoModel()->handleKeyPress( key, velocity ); - - // set panning of newly played key - midiEvent evt( MidiMetaEvent, 0, key, pan ); - evt.m_metaEvent = MidiNotePanning; } @@ -2183,9 +2178,9 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) // convert to ticks so that we can check which notes // are in the range int ticks_start = (x-pixel_range/2) * - midiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerTact() / m_ppt + m_currentPosition; int ticks_end = (x+pixel_range/2) * - midiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerTact() / m_ppt + m_currentPosition; // get note-vector of current pattern const NoteVector & notes = m_pattern->notes(); @@ -2233,15 +2228,14 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) if( m_noteEditMode == NoteEditVolume ) { n->setVolume( vol ); - m_pattern->instrumentTrack()->processInEvent( - midiEvent( MidiKeyPressure, 0, n->key(), volumeToMidi( vol ) ), midiTime() ); + m_pattern->instrumentTrack()->processInEvent( MidiEvent( MidiKeyPressure, 0, n->key(), volumeToMidi( vol ) ) ); } else if( m_noteEditMode == NoteEditPanning ) { n->setPanning( pan ); - midiEvent evt( MidiMetaEvent, 0, n->key(), panningToMidi( pan ) ); - evt.m_metaEvent = MidiNotePanning; - m_pattern->instrumentTrack()->processInEvent( evt, midiTime() ); + MidiEvent evt( MidiMetaEvent, 0, n->key(), panningToMidi( pan ) ); + evt.setMetaEvent( MidiNotePanning ); + m_pattern->instrumentTrack()->processInEvent( evt ); } } else @@ -2264,7 +2258,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) // set move- or resize-cursor // get tick in which the cursor is posated - int pos_ticks = ( x * midiTime::ticksPerTact() ) / + int pos_ticks = ( x * MidiTime::ticksPerTact() ) / m_ppt + m_currentPosition; // get note-vector of current pattern @@ -2296,10 +2290,10 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) // cursor at the "tail" of the note? if( ( *it )->length() > 0 && pos_ticks*m_ppt / - midiTime::ticksPerTact() > + MidiTime::ticksPerTact() > ( ( *it )->pos() + ( *it )->length() )*m_ppt/ - midiTime::ticksPerTact()- + MidiTime::ticksPerTact()- RESIZE_AREA_WIDTH ) { if( QApplication::overrideCursor() ) @@ -2363,7 +2357,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) // change size of selection // get tick in which the cursor is posated - int pos_ticks = x * midiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + m_currentPosition; m_selectedTick = pos_ticks - m_selectStartTick; @@ -2383,7 +2377,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) // holding down right-click to delete notes // get tick in which the user clicked - int pos_ticks = x * midiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + m_currentPosition; @@ -2396,7 +2390,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) // loop through whole note-vector... while( it != notes.end() ) { - midiTime len = ( *it )->length(); + MidiTime len = ( *it )->length(); if( len < 0 ) { len = 4; @@ -2413,7 +2407,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) ( edit_note == true && pos_ticks <= ( *it )->pos() + NE_LINE_WIDTH * - midiTime::ticksPerTact() / + MidiTime::ticksPerTact() / m_ppt ) ) ) @@ -2474,7 +2468,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) } // get tick in which the cursor is posated - int pos_ticks = x * midiTime::ticksPerTact()/ m_ppt + + int pos_ticks = x * MidiTime::ticksPerTact()/ m_ppt + m_currentPosition; m_selectedTick = pos_ticks - @@ -2535,7 +2529,7 @@ void pianoRoll::dragNotes( int x, int y, bool alt, bool shift ) // convert pixels to ticks and keys int off_x = x - m_moveStartX; - int off_ticks = off_x * midiTime::ticksPerTact() / m_ppt; + int off_ticks = off_x * MidiTime::ticksPerTact() / m_ppt; int off_key = getKey( y ) - getKey( m_moveStartY ); // handle scroll changes while dragging @@ -2587,7 +2581,7 @@ void pianoRoll::dragNotes( int x, int y, bool alt, bool shift ) { shifted_pos -= off_ticks; } - ( *it )->setPos( midiTime( shifted_pos ) ); + ( *it )->setPos( MidiTime( shifted_pos ) ); } if( ( *it )->selected() ) @@ -2614,7 +2608,7 @@ void pianoRoll::dragNotes( int x, int y, bool alt, bool shift ) key_num = NumKeys; } - ( *it )->setPos( midiTime( pos_ticks ) ); + ( *it )->setPos( MidiTime( pos_ticks ) ); ( *it )->setKey( key_num ); } else if( m_action == ActionResizeNote ) @@ -2636,7 +2630,7 @@ void pianoRoll::dragNotes( int x, int y, bool alt, bool shift ) shift_ref_pos = pos; } } - ( *it )->setLength( midiTime( ticks_new ) ); + ( *it )->setLength( MidiTime( ticks_new ) ); m_lenOfNewNotes = ( *it )->length(); } @@ -2941,7 +2935,7 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) // triplet mode occurs if the note duration isn't a multiple of 3 bool triplets = ( quantization() % 3 != 0 ); - int spt = midiTime::stepsPerTact(); + int spt = MidiTime::stepsPerTact(); float pp16th = (float)m_ppt / spt; int bpt = DefaultBeatsPerTact; if ( triplets ) { @@ -2953,7 +2947,7 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) int tact_16th = m_currentPosition / bpt; const int offset = ( m_currentPosition % bpt ) * - m_ppt / midiTime::ticksPerTact(); + m_ppt / MidiTime::ticksPerTact(); bool show32nds = ( m_zoomingModel.value() > 3 ); @@ -3047,9 +3041,9 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) int pos_ticks = ( *it )->pos(); int note_width = len_ticks * m_ppt / - midiTime::ticksPerTact(); + MidiTime::ticksPerTact(); const int x = ( pos_ticks - m_currentPosition ) * - m_ppt / midiTime::ticksPerTact(); + m_ppt / MidiTime::ticksPerTact(); // skip this note if not in visible area at all if( !( x + note_width >= 0 && x <= width() - WHITE_KEY_WIDTH ) ) @@ -3141,9 +3135,9 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) // now draw selection-frame int x = ( ( sel_pos_start - m_currentPosition ) * m_ppt ) / - midiTime::ticksPerTact(); + MidiTime::ticksPerTact(); int w = ( ( ( sel_pos_end - m_currentPosition ) * m_ppt ) / - midiTime::ticksPerTact() ) - x; + MidiTime::ticksPerTact() ) - x; int y = (int) y_base - sel_key_start * KEY_LINE_HEIGHT; int h = (int) y_base - sel_key_end * KEY_LINE_HEIGHT - y; p.setPen( QColor( 0, 64, 192 ) ); @@ -3407,7 +3401,7 @@ void pianoRoll::startRecordNote( const note & _n ) engine::getSong()->playMode() == song::Mode_PlayPattern ) ) { - midiTime sub; + MidiTime sub; if( engine::getSong()->playMode() == song::Mode_PlaySong ) { sub = m_pattern->startPosition(); @@ -3596,7 +3590,7 @@ void pianoRoll::copy_to_clipboard( const NoteVector & _notes ) const QDomElement note_list = mmp.createElement( "note-list" ); mmp.content().appendChild( note_list ); - midiTime start_pos( _notes.front()->pos().getTact(), 0 ); + MidiTime start_pos( _notes.front()->pos().getTact(), 0 ); for( NoteVector::ConstIterator it = _notes.begin(); it != _notes.end(); ++it ) { @@ -3752,20 +3746,20 @@ void pianoRoll::deleteSelectedNotes() -void pianoRoll::autoScroll( const midiTime & _t ) +void pianoRoll::autoScroll( const MidiTime & _t ) { const int w = width() - WHITE_KEY_WIDTH; - if( _t > m_currentPosition + w * midiTime::ticksPerTact() / m_ppt ) + if( _t > m_currentPosition + w * MidiTime::ticksPerTact() / m_ppt ) { m_leftRightScroll->setValue( _t.getTact() * - midiTime::ticksPerTact() ); + MidiTime::ticksPerTact() ); } else if( _t < m_currentPosition ) { - midiTime t = qMax( _t - w * midiTime::ticksPerTact() * - midiTime::ticksPerTact() / m_ppt, 0 ); + MidiTime t = qMax( _t - w * MidiTime::ticksPerTact() * + MidiTime::ticksPerTact() / m_ppt, 0 ); m_leftRightScroll->setValue( t.getTact() * - midiTime::ticksPerTact() ); + MidiTime::ticksPerTact() ); } m_scrollBack = false; } @@ -3773,7 +3767,7 @@ void pianoRoll::autoScroll( const midiTime & _t ) -void pianoRoll::updatePosition( const midiTime & _t ) +void pianoRoll::updatePosition( const MidiTime & _t ) { if( ( engine::getSong()->isPlaying() && engine::getSong()->playMode() == @@ -3788,14 +3782,14 @@ void pianoRoll::updatePosition( const midiTime & _t ) -void pianoRoll::updatePositionAccompany( const midiTime & _t ) +void pianoRoll::updatePositionAccompany( const MidiTime & _t ) { song * s = engine::getSong(); if( m_recording && validPattern() && s->playMode() != song::Mode_PlayPattern ) { - midiTime pos = _t; + MidiTime pos = _t; if( s->playMode() != song::Mode_PlayBB ) { pos -= m_pattern->startPosition(); @@ -3868,7 +3862,7 @@ void pianoRoll::updateSemiToneMarkerMenu() -midiTime pianoRoll::newNoteLen() const +MidiTime pianoRoll::newNoteLen() const { if( m_noteLenModel.value() == 0 ) { @@ -3906,7 +3900,7 @@ note * pianoRoll::noteUnderMouse() int key_num = getKey( pos.y() ); int pos_ticks = ( pos.x() - WHITE_KEY_WIDTH ) * - midiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerTact() / m_ppt + m_currentPosition; // will be our iterator in the following loop NoteVector::ConstIterator it = notes.begin()+notes.size()-1; diff --git a/src/gui/setup_dialog.cpp b/src/gui/setup_dialog.cpp index 0b0526aee5..d863833b67 100644 --- a/src/gui/setup_dialog.cpp +++ b/src/gui/setup_dialog.cpp @@ -1,7 +1,7 @@ /* * setup_dialog.cpp - dialog for setting up LMMS * - * Copyright (c) 2005-2013 Tobias Doerffel + * Copyright (c) 2005-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -108,10 +108,6 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) : m_stkDir( configManager::inst()->stkDir() ), #endif m_backgroundArtwork( configManager::inst()->backgroundArtwork() ), - m_disableChActInd( configManager::inst()->value( "ui", - "disablechannelactivityindicators" ).toInt() ), - m_manualChPiano( configManager::inst()->value( "ui", - "manualchannelpiano" ).toInt() ), m_smoothScroll( configManager::inst()->value( "ui", "smoothscroll" ).toInt() ), m_enableAutoSave( configManager::inst()->value( "ui", "enableautosave" ).toInt() ), m_oneInstrumentTrackWindow( configManager::inst()->value( "ui", @@ -513,28 +509,11 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) : tabWidget * ui_fx_tw = new tabWidget( tr( "UI effects vs. " "performance" ).toUpper(), performance ); - ui_fx_tw->setFixedHeight( 120 ); - - ledCheckBox * disable_ch_act_ind = new ledCheckBox( - tr( "Disable channel activity indicators" ), - ui_fx_tw ); - disable_ch_act_ind->move( 10, 20 ); - disable_ch_act_ind->setChecked( m_disableChActInd ); - connect( disable_ch_act_ind, SIGNAL( toggled( bool ) ), - this, SLOT( toggleDisableChActInd( bool ) ) ); - - - ledCheckBox * manual_ch_piano = new ledCheckBox( - tr( "Only press keys on channel-piano manually" ), - ui_fx_tw ); - manual_ch_piano->move( 10, 40 ); - manual_ch_piano->setChecked( m_manualChPiano ); - connect( manual_ch_piano, SIGNAL( toggled( bool ) ), - this, SLOT( toggleManualChPiano( bool ) ) ); + ui_fx_tw->setFixedHeight( 80 ); ledCheckBox * smoothScroll = new ledCheckBox( tr( "Smooth scroll in Song Editor" ), ui_fx_tw ); - smoothScroll->move( 10, 60 ); + smoothScroll->move( 10, 20 ); smoothScroll->setChecked( m_smoothScroll ); connect( smoothScroll, SIGNAL( toggled( bool ) ), this, SLOT( toggleSmoothScroll( bool ) ) ); @@ -542,7 +521,7 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) : ledCheckBox * autoSave = new ledCheckBox( tr( "Enable auto save feature" ), ui_fx_tw ); - autoSave->move( 10, 80 ); + autoSave->move( 10, 40 ); autoSave->setChecked( m_enableAutoSave ); connect( autoSave, SIGNAL( toggled( bool ) ), this, SLOT( toggleAutoSave( bool ) ) ); @@ -551,7 +530,7 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) : ledCheckBox * animAFP = new ledCheckBox( tr( "Show playback cursor in AudioFileProcessor" ), ui_fx_tw ); - animAFP->move( 10, 100 ); + animAFP->move( 10, 60 ); animAFP->setChecked( m_animateAFP ); connect( animAFP, SIGNAL( toggled( bool ) ), this, SLOT( toggleAnimateAFP( bool ) ) ); @@ -818,11 +797,6 @@ void setupDialog::accept() QString::number( !m_MMPZ ) ); configManager::inst()->setValue( "mixer", "hqaudio", QString::number( m_hqAudioDev ) ); - configManager::inst()->setValue( "ui", - "disablechannelactivityindicators", - QString::number( m_disableChActInd ) ); - configManager::inst()->setValue( "ui", "manualchannelpiano", - QString::number( m_manualChPiano ) ); configManager::inst()->setValue( "ui", "smoothscroll", QString::number( m_smoothScroll ) ); configManager::inst()->setValue( "ui", "enableautosave", @@ -979,23 +953,6 @@ void setupDialog::toggleHQAudioDev( bool _enabled ) -void setupDialog::toggleDisableChActInd( bool _disabled ) -{ - m_disableChActInd = _disabled; -} - - - - -void setupDialog::toggleManualChPiano( bool _enabled ) -{ - m_manualChPiano = _enabled; -} - - - - - void setupDialog::toggleSmoothScroll( bool _enabled ) { m_smoothScroll = _enabled; diff --git a/src/gui/song_editor.cpp b/src/gui/song_editor.cpp index 60d7ed256b..0992046169 100644 --- a/src/gui/song_editor.cpp +++ b/src/gui/song_editor.cpp @@ -99,11 +99,11 @@ songEditor::songEditor( song * _song, songEditor * & _engine_ptr ) : pixelsPerTact(), m_s->m_playPos[song::Mode_PlaySong], m_currentPosition, this ); - connect( this, SIGNAL( positionChanged( const midiTime & ) ), + connect( this, SIGNAL( positionChanged( const MidiTime & ) ), m_s->m_playPos[song::Mode_PlaySong].m_timeLine, - SLOT( updatePosition( const midiTime & ) ) ); - connect( m_timeLine, SIGNAL( positionChanged( const midiTime & ) ), - this, SLOT( updatePosition( const midiTime & ) ) ); + SLOT( updatePosition( const MidiTime & ) ) ); + connect( m_timeLine, SIGNAL( positionChanged( const MidiTime & ) ), + this, SLOT( updatePosition( const MidiTime & ) ) ); m_positionLine = new positionLine( this ); @@ -113,7 +113,7 @@ songEditor::songEditor( song * _song, songEditor * & _engine_ptr ) : this, SLOT( adjustUiAfterProjectLoad() ) ); - // add some essential widgets to global tool-bar + // add some essential widgets to global tool-bar QWidget * tb = engine::mainWindow()->toolBar(); engine::mainWindow()->addSpacingToToolBar( 10 ); @@ -153,7 +153,7 @@ songEditor::songEditor( song * _song, songEditor * & _engine_ptr ) : engine::mainWindow()->addWidgetToToolBar( m_timeSigDisplay ); engine::mainWindow()->addSpacingToToolBar( 10 ); - + QLabel * master_vol_lbl = new QLabel( tb ); master_vol_lbl->setPixmap( embed::getIconPixmap( "master_volume" ) ); @@ -239,7 +239,7 @@ songEditor::songEditor( song * _song, songEditor * & _engine_ptr ) : m_toolBar->setFixedHeight( 32 ); m_toolBar->setAutoFillBackground( true ); QPalette pal; - pal.setBrush( m_toolBar->backgroundRole(), + pal.setBrush( m_toolBar->backgroundRole(), embed::getIconPixmap( "toolbar_bg" ) ); m_toolBar->setPalette( pal ); @@ -255,19 +255,23 @@ songEditor::songEditor( song * _song, songEditor * & _engine_ptr ) : m_playButton = new toolButton( embed::getIconPixmap( "play" ), tr( "Play song (Space)" ), this, SLOT( play() ), m_toolBar ); + m_playButton->setObjectName( "playButton" ); m_recordButton = new toolButton( embed::getIconPixmap( "record" ), tr( "Record samples from Audio-device" ), this, SLOT( record() ), m_toolBar ); - m_recordAccompanyButton = new toolButton( + m_recordButton->setObjectName( "recordButton" ); + + m_recordAccompanyButton = new toolButton( embed::getIconPixmap( "record_accompany" ), tr( "Record samples from Audio-device while playing " "song or BB track" ), this, SLOT( recordAccompany() ), m_toolBar ); + m_recordAccompanyButton->setObjectName( "recordAccompanyButton" ); // FIXME: disable record button while it is not implemented m_recordButton->setDisabled( true ); - + // disable record buttons if capturing is not supported if( !engine::mixer()->audioDev()->supportsCapture() ) { @@ -278,6 +282,7 @@ songEditor::songEditor( song * _song, songEditor * & _engine_ptr ) : m_stopButton = new toolButton( embed::getIconPixmap( "stop" ), tr( "Stop song (Space)" ), this, SLOT( stop() ), m_toolBar ); + m_stopButton->setObjectName( "stopButton" ); m_addBBTrackButton = new toolButton( embed::getIconPixmap( "add_bb_track" ), @@ -419,7 +424,7 @@ void songEditor::setHighQuality( bool _hq ) void songEditor::scrolled( int _new_pos ) { update(); - emit positionChanged( m_currentPosition = midiTime( _new_pos, 0 ) ); + emit positionChanged( m_currentPosition = MidiTime( _new_pos, 0 ) ); } @@ -503,7 +508,7 @@ void songEditor::keyPressEvent( QKeyEvent * _ke ) } else if( _ke->key() == Qt::Key_Left ) { - tick_t t = m_s->currentTick() - midiTime::ticksPerTact(); + tick_t t = m_s->currentTick() - MidiTime::ticksPerTact(); if( t >= 0 ) { m_s->setPlayPos( t, song::Mode_PlaySong ); @@ -511,7 +516,7 @@ void songEditor::keyPressEvent( QKeyEvent * _ke ) } else if( _ke->key() == Qt::Key_Right ) { - tick_t t = m_s->currentTick() + midiTime::ticksPerTact(); + tick_t t = m_s->currentTick() + MidiTime::ticksPerTact(); if( t < MaxSongLength ) { m_s->setPlayPos( t, song::Mode_PlaySong ); @@ -566,7 +571,7 @@ void songEditor::wheelEvent( QWheelEvent * _we ) setPixelsPerTact( pixelsPerTact() ); // and make sure, all TCO's are resized and relocated realignTracks(); - } + } else if( engine::mainWindow()->isShiftPressed() == TRUE ) { m_leftRightScroll->setValue( m_leftRightScroll->value() - @@ -706,7 +711,7 @@ static inline void animateScroll( QScrollBar *scrollBar, int newVal, bool smooth } -void songEditor::updatePosition( const midiTime & _t ) +void songEditor::updatePosition( const MidiTime & _t ) { int widgetWidth, trackOpWidth; if( configManager::inst()->value( "ui", "compacttrackbuttons" ).toInt() ) @@ -720,22 +725,22 @@ void songEditor::updatePosition( const midiTime & _t ) trackOpWidth = TRACK_OP_WIDTH; } - if( ( m_s->isPlaying() && m_s->m_playMode == song::Mode_PlaySong + if( ( m_s->isPlaying() && m_s->m_playMode == song::Mode_PlaySong && m_timeLine->autoScroll() == timeLine::AutoScrollEnabled) || m_scrollBack == true ) { const int w = width() - widgetWidth - trackOpWidth - 32; // rough estimation for width of right scrollbar - if( _t > m_currentPosition + w * midiTime::ticksPerTact() / + if( _t > m_currentPosition + w * MidiTime::ticksPerTact() / pixelsPerTact() ) { animateScroll( m_leftRightScroll, _t.getTact(), m_smoothScroll ); } else if( _t < m_currentPosition ) { - midiTime t = qMax( - (int)( _t - w * midiTime::ticksPerTact() / + MidiTime t = qMax( + (int)( _t - w * MidiTime::ticksPerTact() / pixelsPerTact() ), 0 ); animateScroll( m_leftRightScroll, t.getTact(), m_smoothScroll ); diff --git a/src/gui/widgets/EffectView.cpp b/src/gui/widgets/EffectView.cpp index 9b6b8cc05f..d61adc9665 100644 --- a/src/gui/widgets/EffectView.cpp +++ b/src/gui/widgets/EffectView.cpp @@ -158,8 +158,11 @@ EffectView::~EffectView() delete m_subWindow; #else - // otherwise on win32 build VST GUI can get lost - m_subWindow->hide(); + if( m_subWindow ) + { + // otherwise on win32 build VST GUI can get lost + m_subWindow->hide(); + } #endif } diff --git a/src/gui/widgets/cpuload_widget.cpp b/src/gui/widgets/cpuload_widget.cpp index 508581a742..f634a6b1ef 100644 --- a/src/gui/widgets/cpuload_widget.cpp +++ b/src/gui/widgets/cpuload_widget.cpp @@ -45,6 +45,7 @@ cpuloadWidget::cpuloadWidget( QWidget * _parent ) : setFixedSize( m_background.width(), m_background.height() ); m_temp = QPixmap( width(), height() ); + connect( &m_updateTimer, SIGNAL( timeout() ), this, SLOT( updateCpuLoad() ) ); @@ -66,7 +67,8 @@ void cpuloadWidget::paintEvent( QPaintEvent * ) if( m_changed == true ) { m_changed = false; - + + m_temp.fill( QColor(0,0,0,0) ); QPainter p( &m_temp ); p.drawPixmap( 0, 0, m_background ); diff --git a/src/gui/widgets/fader.cpp b/src/gui/widgets/fader.cpp index b9f3016633..f2dc4c5fd8 100644 --- a/src/gui/widgets/fader.cpp +++ b/src/gui/widgets/fader.cpp @@ -290,7 +290,7 @@ void fader::paintEvent( QPaintEvent * ev) if( m_persistentPeak_L > 0.05 ) { - painter.fillRect( QRect( 2, persistentPeak_L, 4, 1 ), (m_persistentPeak_L < 1.0 )? QColor( 74, 253, 133) : QColor( 255, 100, 100)); + painter.fillRect( QRect( 2, persistentPeak_L, 7, 1 ), (m_persistentPeak_L < 1.0 )? QColor( 74, 253, 133) : QColor( 255, 100, 100)); } int peak_R = calculateDisplayPeak( m_fPeakValue_R - m_fMinPeak ); @@ -299,7 +299,7 @@ void fader::paintEvent( QPaintEvent * ev) if( m_persistentPeak_R > 0.05 ) { - painter.fillRect( QRect( 16, persistentPeak_R, 4, 1 ), (m_persistentPeak_R < 1.0 )? QColor( 74, 253, 133) : QColor( 255, 100, 100)); + painter.fillRect( QRect( 14, persistentPeak_R, 7, 1 ), (m_persistentPeak_R < 1.0 )? QColor( 74, 253, 133) : QColor( 255, 100, 100)); } // knob diff --git a/src/gui/widgets/knob.cpp b/src/gui/widgets/knob.cpp index 1c8dc9eaf0..e03d2a6fc6 100644 --- a/src/gui/widgets/knob.cpp +++ b/src/gui/widgets/knob.cpp @@ -352,6 +352,7 @@ void knob::drawKnob( QPainter * _p ) } case knobDark_28: { + p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::WindowText ), 2 ) ); const float rb = qMax( ( radius - 10 ) / 3.0, 0.0 ); const float re = qMax( ( radius - 4 ), 0.0 ); @@ -379,7 +380,7 @@ void knob::drawKnob( QPainter * _p ) float knob::getValue( const QPoint & _p ) { const float SMOOTH_FACTOR = 0.125f; - int yDist = (_p.y() - m_origMousePos.y()) * SMOOTH_FACTOR; + float yDist = (_p.y() - m_origMousePos.y()) * SMOOTH_FACTOR; if( engine::mainWindow()->isShiftPressed() ) { return m_origValue - (yDist * model()->step()); diff --git a/src/gui/widgets/track_label_button.cpp b/src/gui/widgets/track_label_button.cpp index 0080c090cc..f264857019 100644 --- a/src/gui/widgets/track_label_button.cpp +++ b/src/gui/widgets/track_label_button.cpp @@ -58,7 +58,7 @@ trackLabelButton::trackLabelButton( trackView * _tv, QWidget * _parent ) : setFixedSize( 160, 29 ); } - setIconSize( QSize( 32, 32 ) ); + setIconSize( QSize( 24, 24 ) ); setText( " " ); connect( m_trackView->getTrack(), SIGNAL( dataChanged() ), diff --git a/src/gui/widgets/visualization_widget.cpp b/src/gui/widgets/visualization_widget.cpp index 7dee75d33c..2f6eebe95d 100644 --- a/src/gui/widgets/visualization_widget.cpp +++ b/src/gui/widgets/visualization_widget.cpp @@ -141,7 +141,7 @@ void visualizationWidget::paintEvent( QPaintEvent * ) // and set color according to that... if( max_level * master_output < 0.9 ) { - p.setPen( QColor( 128, 224, 128 ) ); + p.setPen( QColor( 71, 253, 133 ) ); } else if( max_level * master_output < 1.0 ) { diff --git a/src/tracks/AutomationTrack.cpp b/src/tracks/AutomationTrack.cpp index 5988ba3c5d..3353ae3eb2 100644 --- a/src/tracks/AutomationTrack.cpp +++ b/src/tracks/AutomationTrack.cpp @@ -50,7 +50,7 @@ AutomationTrack::~AutomationTrack() -bool AutomationTrack::play( const midiTime & _start, const fpp_t _frames, +bool AutomationTrack::play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num ) { if( isMuted() ) @@ -77,7 +77,7 @@ bool AutomationTrack::play( const midiTime & _start, const fpp_t _frames, { continue; } - midiTime cur_start = _start; + MidiTime cur_start = _start; if( _tco_num < 0 ) { cur_start -= p->startPosition(); @@ -98,7 +98,7 @@ trackView * AutomationTrack::createView( TrackContainerView* tcv ) -trackContentObject * AutomationTrack::createTCO( const midiTime & ) +trackContentObject * AutomationTrack::createTCO( const MidiTime & ) { return new AutomationPattern( this ); } @@ -168,11 +168,11 @@ void AutomationTrackView::dropEvent( QDropEvent * _de ) journallingObject( val.toInt() ) ); if( mod != NULL ) { - midiTime pos = midiTime( trackContainerView()-> + MidiTime pos = MidiTime( trackContainerView()-> currentPosition() + ( _de->pos().x() - getTrackContentWidget()->x() ) * - midiTime::ticksPerTact() / + MidiTime::ticksPerTact() / static_cast( trackContainerView()->pixelsPerTact() ) ) .toNearestTact(); diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index a88f07fcbc..b7412f19f3 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -103,7 +103,7 @@ InstrumentTrack::InstrumentTrack( TrackContainer* tc ) : tr( "Base note" ) ), m_volumeModel( DefaultVolume, MinVolume, MaxVolume, 0.1f, this, tr( "Volume" ) ), m_panningModel( DefaultPanning, PanningLeft, PanningRight, 0.1f, this, tr( "Panning" ) ), - m_pitchModel( 0, -100, 100, 1, this, tr( "Pitch" ) ), + m_pitchModel( 0, MinPitchDefault, MaxPitchDefault, 1, this, tr( "Pitch" ) ), m_pitchRangeModel( 1, 1, 24, this, tr( "Pitch range" ) ), m_effectChannelModel( 0, 0, NumFxChannels, this, tr( "FX channel" ) ), m_instrument( NULL ), @@ -202,15 +202,15 @@ void InstrumentTrack::processAudioBuffer( sampleFrame * _buf, -midiEvent InstrumentTrack::applyMasterKey( const midiEvent & _me ) +MidiEvent InstrumentTrack::applyMasterKey( const MidiEvent& event ) { - midiEvent copy( _me ); - switch( _me.m_type ) + MidiEvent copy( event ); + switch( event.type() ) { case MidiNoteOn: case MidiNoteOff: case MidiKeyPressure: - copy.key() = masterKey( _me.key() ); + copy.setKey( masterKey( event.key() ) ); break; default: break; @@ -221,109 +221,69 @@ midiEvent InstrumentTrack::applyMasterKey( const midiEvent & _me ) -void InstrumentTrack::processInEvent( const midiEvent & _me, - const midiTime & _time ) +void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& time ) { engine::mixer()->lock(); - // in the special case this event comes from a MIDI port, the instrument - // is MIDI based (VST plugin, Sf2Player etc.) and the user did not set - // a dedicated MIDI output channel, directly pass the MIDI event to the - // instrument plugin - if( _me.isFromMidiPort() && m_instrument->isMidiBased()/* && - midiPort()->realOutputChannel() < 0 */ ) - { - m_instrument->handleMidiEvent( _me, _time ); - engine::mixer()->unlock(); - return; - } + bool eventHandled = false; - switch( _me.m_type ) + switch( event.type() ) { // we don't send MidiNoteOn, MidiNoteOff and MidiKeyPressure // events to instrument as notePlayHandle will send them on its // own - case MidiNoteOn: - if( _me.velocity() > 0 ) + case MidiNoteOn: + if( event.velocity() > 0 ) { - if( m_notes[_me.key()] == NULL ) + if( m_notes[event.key()] == NULL ) { - if( !configManager::inst()->value( "ui", - "manualchannelpiano" ).toInt() ) - { - m_piano.setKeyState( - _me.key(), true ); - } - // create temporary note - note n; - n.setKey( _me.key() ); - n.setVolume( _me.getVolume() ); - // create (timed) note-play-handle - notePlayHandle * nph = new - notePlayHandle( this, - _time.frames( - engine::framesPerTick() ), - typeInfo::max() / 2, - n ); - if( engine::mixer()->addPlayHandle( - nph ) ) + notePlayHandle* nph = new notePlayHandle( this, time.frames( engine::framesPerTick() ), + typeInfo::max() / 2, + note( MidiTime(), MidiTime(), event.key(), event.volume() ), + NULL, false, event.channel(), + notePlayHandle::OriginMidiInput ); + if( engine::mixer()->addPlayHandle( nph ) ) { - m_notes[_me.key()] = nph; + m_notes[event.key()] = nph; } - - emit noteOn( n ); } + + eventHandled = true; break; } case MidiNoteOff: - { - notePlayHandle * n = m_notes[_me.key()]; - if( n != NULL ) + if( m_notes[event.key()] != NULL ) { - // create dummy-note which has the same length - // as the played note for sending it later - // to all slots connected to signal noteOff() - // this is for example needed by piano-roll for - // recording notes into a pattern - note done_note( - midiTime( static_cast( - n->totalFramesPlayed() / - engine::framesPerTick() ) ), - 0, - n->key(), - n->getVolume(), - n->getPanning() ); - - n->noteOff(); - m_notes[_me.key()] = NULL; - - emit noteOff( done_note ); + // do actual note off and remove internal reference to NotePlayHandle (which itself will + // be deleted later automatically) + m_notes[event.key()]->noteOff(); + m_notes[event.key()] = NULL; } + eventHandled = true; break; - } case MidiKeyPressure: - if( m_notes[_me.key()] != NULL ) + if( m_notes[event.key()] != NULL ) { - m_notes[_me.key()]->setVolume( _me.getVolume() ); + // setVolume() calls processOutEvent() with MidiKeyPressure so the + // attached instrument will receive the event as well + m_notes[event.key()]->setVolume( event.volume() ); } + eventHandled = true; break; case MidiPitchBend: - // updatePitch() is connected to - // m_pitchModel::dataChanged() which will send out + // updatePitch() is connected to m_pitchModel::dataChanged() which will send out // MidiPitchBend events - m_pitchModel.setValue( m_pitchModel.minValue() + - _me.m_data.m_param[0] * - m_pitchModel.range() / 16384 ); + m_pitchModel.setValue( m_pitchModel.minValue() + event.pitchBend() * m_pitchModel.range() / MidiMaxPitchBend ); break; case MidiControlChange: - if( _me.controllerNumber() == MidiControllerSustain ) + if( event.controllerNumber() == MidiControllerSustain ) { - if( _me.controllerValue() > MidiMaxControllerValue/2 ) + if( event.controllerValue() > MidiMaxControllerValue/2 ) { m_sustainPedalPressed = true; } @@ -332,120 +292,95 @@ void InstrumentTrack::processInEvent( const midiEvent & _me, m_sustainPedalPressed = false; } } - if( _me.controllerNumber() == MidiControllerAllSoundOff || - _me.controllerNumber() == MidiControllerAllNotesOff || - _me.controllerNumber() == MidiControllerOmniOn || - _me.controllerNumber() == MidiControllerOmniOff || - _me.controllerNumber() == MidiControllerMonoOn || - _me.controllerNumber() == MidiControllerPolyOn ) + if( event.controllerNumber() == MidiControllerAllSoundOff || + event.controllerNumber() == MidiControllerAllNotesOff || + event.controllerNumber() == MidiControllerOmniOn || + event.controllerNumber() == MidiControllerOmniOff || + event.controllerNumber() == MidiControllerMonoOn || + event.controllerNumber() == MidiControllerPolyOn ) { silenceAllNotes(); } - m_instrument->handleMidiEvent( _me, _time ); break; - case MidiProgramChange: - m_instrument->handleMidiEvent( _me, _time ); - break; - case MidiMetaEvent: // handle special cases such as note panning - switch( _me.m_metaEvent ) + switch( event.metaEvent() ) { case MidiNotePanning: - if( m_notes[_me.key()] != NULL ) + if( m_notes[event.key()] != NULL ) { - m_notes[_me.key()]->setPanning( _me.getPanning() ); + eventHandled = true; + m_notes[event.key()]->setPanning( event.panning() ); } break; default: - printf( "instrument-track: unhandled " - "MIDI meta event: %i\n", - _me.m_metaEvent ); + qWarning( "InstrumentTrack: unhandled MIDI meta event: %i", event.metaEvent() ); break; } break; default: - if( !m_instrument->handleMidiEvent( _me, _time ) ) - { - printf( "instrument-track: unhandled " - "MIDI event %d\n", _me.m_type ); - } break; } + + if( eventHandled == false && instrument()->handleMidiEvent( event, time ) == false ) + { + qWarning( "InstrumentTrack: unhandled MIDI event %d", event.type() ); + } + engine::mixer()->unlock(); } -void InstrumentTrack::processOutEvent( const midiEvent & _me, - const midiTime & _time ) +void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& time ) { - int k; + // do nothing if we do not have an instrument instance (e.g. when loading settings) + if( m_instrument == NULL ) + { + return; + } - switch( _me.m_type ) + const MidiEvent transposedEvent = applyMasterKey( event ); + const int key = transposedEvent.key(); + + switch( event.type() ) { case MidiNoteOn: - if( !configManager::inst()->value( "ui", - "manualchannelpiano" ).toInt() ) + m_piano.setKeyState( event.key(), true ); // event.key() = original key + + if( key >= 0 && key < NumKeys ) { - m_piano.setKeyState( _me.key(), true ); - } - if( !configManager::inst()->value( "ui", - "disablechannelactivityindicators" ).toInt() ) - { - if( m_notes[_me.key()] == NULL ) + if( m_runningMidiNotes[key] > 0 ) { - emit newNote(); + m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time ); } - } - k = masterKey( _me.key() ); - if( k >= 0 && k < NumKeys ) - { - if( m_runningMidiNotes[k] > 0 ) - { - m_instrument->handleMidiEvent( - midiEvent( MidiNoteOff, midiPort()->realOutputChannel(), k, 0 ), - _time ); - } - ++m_runningMidiNotes[k]; - m_instrument->handleMidiEvent( - midiEvent( MidiNoteOn, midiPort()->realOutputChannel(), k, - _me.velocity() ), _time ); + ++m_runningMidiNotes[key]; + m_instrument->handleMidiEvent( MidiEvent( MidiNoteOn, midiPort()->realOutputChannel(), key, event.velocity() ), time ); + + emit newNote(); } break; case MidiNoteOff: - if( !configManager::inst()->value( "ui", - "manualchannelpiano" ).toInt() ) + m_piano.setKeyState( event.key(), false ); // event.key() = original key + + if( key >= 0 && key < NumKeys && --m_runningMidiNotes[key] <= 0 ) { - m_piano.setKeyState( _me.key(), false ); - } - k = masterKey( _me.key() ); - if( k >= 0 && k < NumKeys && - --m_runningMidiNotes[k] <= 0 ) - { - m_runningMidiNotes[k] = qMax( 0, m_runningMidiNotes[k] ); - m_instrument->handleMidiEvent( - midiEvent( MidiNoteOff, midiPort()->realOutputChannel(), k, 0 ), - _time ); + m_runningMidiNotes[key] = qMax( 0, m_runningMidiNotes[key] ); + m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time ); } break; default: - if( m_instrument != NULL ) - { - m_instrument->handleMidiEvent( - applyMasterKey( _me ), - _time ); - } + m_instrument->handleMidiEvent( transposedEvent, time ); break; } // if appropriate, midi-port does futher routing - m_midiPort.processOutEvent( _me, _time ); + m_midiPort.processOutEvent( event, time ); } @@ -515,24 +450,11 @@ QString InstrumentTrack::instrumentName() const -void InstrumentTrack::deleteNotePluginData( notePlayHandle * _n ) +void InstrumentTrack::deleteNotePluginData( notePlayHandle* n ) { if( m_instrument != NULL ) { - m_instrument->deleteNotePluginData( _n ); - } - - // Notes deleted when keys still pressed - if( m_notes[_n->key()] == _n ) - { - note done_note( midiTime( static_cast( - _n->totalFramesPlayed() / - engine::framesPerTick() ) ), - 0, _n->key(), - _n->getVolume(), _n->getPanning() ); - _n->noteOff(); - m_notes[_n->key()] = NULL; - emit noteOff( done_note ); + m_instrument->deleteNotePluginData( n ); } } @@ -581,9 +503,8 @@ void InstrumentTrack::updateBaseNote() void InstrumentTrack::updatePitch() { updateBaseNote(); - processOutEvent( midiEvent( MidiPitchBend, - midiPort()->realOutputChannel(), - midiPitch() ), 0 ); + + processOutEvent( MidiEvent( MidiPitchBend, midiPort()->realOutputChannel(), midiPitch() ) ); } @@ -592,7 +513,13 @@ void InstrumentTrack::updatePitch() void InstrumentTrack::updatePitchRange() { const int r = m_pitchRangeModel.value(); - m_pitchModel.setRange( -100 * r, 100 * r ); + m_pitchModel.setRange( MinPitchDefault * r, MaxPitchDefault * r ); + + processOutEvent( MidiEvent( MidiControlChange, midiPort()->realOutputChannel(), + MidiControllerRegisteredParameterNumberLSB, MidiPitchBendSensitivityRPN & 0x7F ) ); + processOutEvent( MidiEvent( MidiControlChange, midiPort()->realOutputChannel(), + MidiControllerRegisteredParameterNumberMSB, ( MidiPitchBendSensitivityRPN >> 8 ) & 0x7F ) ); + processOutEvent( MidiEvent( MidiControlChange, midiPort()->realOutputChannel(), MidiControllerDataEntry, midiPitchRange() ) ); } @@ -616,7 +543,7 @@ void InstrumentTrack::removeMidiPortNode( multimediaProject & _mmp ) -bool InstrumentTrack::play( const midiTime & _start, const fpp_t _frames, +bool InstrumentTrack::play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _offset, int _tco_num ) { const float frames_per_tick = engine::framesPerTick(); @@ -657,7 +584,7 @@ bool InstrumentTrack::play( const midiTime & _start, const fpp_t _frames, { continue; } - midiTime cur_start = _start; + MidiTime cur_start = _start; if( _tco_num < 0 ) { cur_start -= p->startPosition(); @@ -747,7 +674,7 @@ bool InstrumentTrack::play( const midiTime & _start, const fpp_t _frames, -trackContentObject * InstrumentTrack::createTCO( const midiTime & ) +trackContentObject * InstrumentTrack::createTCO( const MidiTime & ) { return new pattern( this ); } @@ -763,77 +690,50 @@ trackView * InstrumentTrack::createView( TrackContainerView* tcv ) -void InstrumentTrack::saveTrackSpecificSettings( QDomDocument & _doc, - QDomElement & _this ) +void InstrumentTrack::saveTrackSpecificSettings( QDomDocument& doc, QDomElement & thisElement ) { - m_volumeModel.saveSettings( _doc, _this, "vol" ); - m_panningModel.saveSettings( _doc, _this, "pan" ); - m_pitchModel.saveSettings( _doc, _this, "pitch" ); - m_pitchRangeModel.saveSettings( _doc, _this, "pitchrange" ); + m_volumeModel.saveSettings( doc, thisElement, "vol" ); + m_panningModel.saveSettings( doc, thisElement, "pan" ); + m_pitchModel.saveSettings( doc, thisElement, "pitch" ); + m_pitchRangeModel.saveSettings( doc, thisElement, "pitchrange" ); - m_effectChannelModel.saveSettings( _doc, _this, "fxch" ); - m_baseNoteModel.saveSettings( _doc, _this, "basenote" ); + m_effectChannelModel.saveSettings( doc, thisElement, "fxch" ); + m_baseNoteModel.saveSettings( doc, thisElement, "basenote" ); if( m_instrument != NULL ) { - QDomElement i = _doc.createElement( "instrument" ); + QDomElement i = doc.createElement( "instrument" ); i.setAttribute( "name", m_instrument->descriptor()->name ); - m_instrument->saveState( _doc, i ); - _this.appendChild( i ); + m_instrument->saveState( doc, i ); + thisElement.appendChild( i ); } - m_soundShaping.saveState( _doc, _this ); - m_noteStacking.saveState( _doc, _this ); - m_arpeggio.saveState( _doc, _this ); - m_midiPort.saveState( _doc, _this ); - m_audioPort.effects()->saveState( _doc, _this ); + m_soundShaping.saveState( doc, thisElement ); + m_noteStacking.saveState( doc, thisElement ); + m_arpeggio.saveState( doc, thisElement ); + m_midiPort.saveState( doc, thisElement ); + m_audioPort.effects()->saveState( doc, thisElement ); } -void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & _this ) +void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement ) { silenceAllNotes(); engine::mixer()->lock(); - m_volumeModel.loadSettings( _this, "vol" ); - - // compat-hacks - move to mmp::upgrade - if( _this.hasAttribute( "surpos" ) || _this.hasAttribute( "surpos-x" ) - || !_this.firstChildElement( "automationpattern" ). - firstChildElement( "surpos-x" ).isNull() ) - { - surroundAreaModel m( this, this ); - m.loadSettings( _this, "surpos" ); - m_panningModel.setValue( m.x() * 100 / SURROUND_AREA_SIZE ); - } - else - { - m_panningModel.loadSettings( _this, "pan" ); - } - - m_pitchModel.loadSettings( _this, "pitch" ); - m_pitchRangeModel.loadSettings( _this, "pitchrange" ); - m_effectChannelModel.loadSettings( _this, "fxch" ); - - if( _this.hasAttribute( "baseoct" ) ) - { - // TODO: move this compat code to mmp.cpp -> upgrade() - m_baseNoteModel.setInitValue( _this. - attribute( "baseoct" ).toInt() - * KeysPerOctave - + _this.attribute( "basetone" ).toInt() ); - } - else - { - m_baseNoteModel.loadSettings( _this, "basenote" ); - } + m_volumeModel.loadSettings( thisElement, "vol" ); + m_panningModel.loadSettings( thisElement, "pan" ); + m_pitchModel.loadSettings( thisElement, "pitch" ); + m_pitchRangeModel.loadSettings( thisElement, "pitchrange" ); + m_effectChannelModel.loadSettings( thisElement, "fxch" ); + m_baseNoteModel.loadSettings( thisElement, "basenote" ); // clear effect-chain just in case we load an old preset without FX-data m_audioPort.effects()->clear(); - QDomNode node = _this.firstChild(); + QDomNode node = thisElement.firstChild(); while( !node.isNull() ) { if( node.isElement() ) @@ -862,11 +762,9 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & _this ) { delete m_instrument; m_instrument = NULL; - m_instrument = Instrument::instantiate( - node.toElement().attribute( "name" ), - this ); - m_instrument->restoreState( - node.firstChildElement() ); + m_instrument = Instrument::instantiate( node.toElement().attribute( "name" ), this ); + m_instrument->restoreState( node.firstChildElement() ); + emit instrumentChanged(); } // compat code - if node-name doesn't match any known @@ -878,19 +776,16 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & _this ) { delete m_instrument; m_instrument = NULL; - m_instrument = Instrument::instantiate( - node.nodeName(), this ); - if( m_instrument->nodeName() == - node.nodeName() ) + m_instrument = Instrument::instantiate( node.nodeName(), this ); + if( m_instrument->nodeName() == node.nodeName() ) { - m_instrument->restoreState( - node.toElement() ); + m_instrument->restoreState( node.toElement() ); } emit instrumentChanged(); } } node = node.nextSibling(); - } + } engine::mixer()->unlock(); } @@ -1181,9 +1076,7 @@ void InstrumentTrackView::toggleInstrumentWindow( bool _on ) void InstrumentTrackView::activityIndicatorPressed() { - model()->processInEvent( - midiEvent( MidiNoteOn, 0, DefaultKey, MidiMaxVelocity ), - midiTime() ); + model()->processInEvent( MidiEvent( MidiNoteOn, 0, DefaultKey, MidiMaxVelocity ) ); } @@ -1191,8 +1084,7 @@ void InstrumentTrackView::activityIndicatorPressed() void InstrumentTrackView::activityIndicatorReleased() { - model()->processInEvent( midiEvent( MidiNoteOff, 0, DefaultKey, 0 ), - midiTime() ); + model()->processInEvent( MidiEvent( MidiNoteOff, 0, DefaultKey, 0 ) ); } @@ -1203,8 +1095,7 @@ void InstrumentTrackView::midiInSelected() { if( model() ) { - model()->m_midiPort.setReadable( - m_midiInputAction->isChecked() ); + model()->m_midiPort.setReadable( m_midiInputAction->isChecked() ); } } @@ -1215,8 +1106,7 @@ void InstrumentTrackView::midiOutSelected() { if( model() ) { - model()->m_midiPort.setWritable( - m_midiOutputAction->isChecked() ); + model()->m_midiPort.setWritable( m_midiOutputAction->isChecked() ); } } @@ -1419,13 +1309,14 @@ InstrumentTrackWindow::~InstrumentTrackWindow() -void InstrumentTrackWindow::setInstrumentTrackView( InstrumentTrackView * _tv ) +void InstrumentTrackWindow::setInstrumentTrackView( InstrumentTrackView* view ) { - if( m_itv && _tv ) + if( m_itv && view ) { m_itv->m_tlb->setChecked( false ); } - m_itv = _tv; + + m_itv = view; } @@ -1475,28 +1366,27 @@ void InstrumentTrackWindow::modelChanged() void InstrumentTrackWindow::saveSettingsBtnClicked() { - FileDialog sfd( this, tr( "Save preset" ), "", - tr( "XML preset file (*.xpf)" ) ); + FileDialog sfd( this, tr( "Save preset" ), "", tr( "XML preset file (*.xpf)" ) ); - QString preset_root = configManager::inst()->userPresetsDir(); - if( !QDir( preset_root ).exists() ) + QString presetRoot = configManager::inst()->userPresetsDir(); + if( !QDir( presetRoot ).exists() ) { - QDir().mkdir( preset_root ); + QDir().mkdir( presetRoot ); } - if( !QDir( preset_root + m_track->instrumentName() ).exists() ) + if( !QDir( presetRoot + m_track->instrumentName() ).exists() ) { - QDir( preset_root ).mkdir( m_track->instrumentName() ); + QDir( presetRoot ).mkdir( m_track->instrumentName() ); } sfd.setAcceptMode( FileDialog::AcceptSave ); - sfd.setDirectory( preset_root + m_track->instrumentName() ); + sfd.setDirectory( presetRoot + m_track->instrumentName() ); sfd.setFileMode( FileDialog::AnyFile ); - if( sfd.exec () == QDialog::Accepted && - !sfd.selectedFiles().isEmpty() && sfd.selectedFiles()[0] != "" - ) + + if( sfd.exec() == QDialog::Accepted && + !sfd.selectedFiles().isEmpty() && + !sfd.selectedFiles().first().isEmpty() ) { - multimediaProject mmp( - multimediaProject::InstrumentTrackSettings ); + multimediaProject mmp( multimediaProject::InstrumentTrackSettings ); m_track->setSimpleSerializing(); m_track->saveSettings( mmp, mmp.content() ); QString f = sfd.selectedFiles()[0]; @@ -1527,8 +1417,7 @@ void InstrumentTrackWindow::updateInstrumentView() delete m_instrumentView; if( m_track->m_instrument != NULL ) { - m_instrumentView = m_track->m_instrument->createView( - m_tabWidget ); + m_instrumentView = m_track->m_instrument->createView( m_tabWidget ); m_tabWidget->addTab( m_instrumentView, tr( "PLUGIN" ), 0 ); m_tabWidget->setActiveTab( 0 ); @@ -1540,19 +1429,18 @@ void InstrumentTrackWindow::updateInstrumentView() -void InstrumentTrackWindow::textChanged( const QString & _new_name ) +void InstrumentTrackWindow::textChanged( const QString& newName ) { - m_track->setName( _new_name ); + m_track->setName( newName ); engine::getSong()->setModified(); } -void InstrumentTrackWindow::toggleVisibility( bool _on ) +void InstrumentTrackWindow::toggleVisibility( bool on ) { - - if( _on ) + if( on ) { show(); parentWidget()->show(); @@ -1567,9 +1455,10 @@ void InstrumentTrackWindow::toggleVisibility( bool _on ) -void InstrumentTrackWindow::closeEvent( QCloseEvent * _ce ) +void InstrumentTrackWindow::closeEvent( QCloseEvent* event ) { - _ce->ignore(); + event->ignore(); + if( engine::mainWindow()->workspace() ) { parentWidget()->hide(); @@ -1578,6 +1467,7 @@ void InstrumentTrackWindow::closeEvent( QCloseEvent * _ce ) { hide(); } + m_itv->m_tlb->setFocus(); m_itv->m_tlb->setChecked( false ); } @@ -1585,7 +1475,7 @@ void InstrumentTrackWindow::closeEvent( QCloseEvent * _ce ) -void InstrumentTrackWindow::focusInEvent( QFocusEvent * ) +void InstrumentTrackWindow::focusInEvent( QFocusEvent* ) { m_pianoView->setFocus(); } @@ -1593,32 +1483,34 @@ void InstrumentTrackWindow::focusInEvent( QFocusEvent * ) -void InstrumentTrackWindow::dragEnterEventGeneric( QDragEnterEvent * _dee ) +void InstrumentTrackWindow::dragEnterEventGeneric( QDragEnterEvent* event ) { - stringPairDrag::processDragEnterEvent( _dee, "instrument,presetfile," - "pluginpresetfile" ); + stringPairDrag::processDragEnterEvent( event, "instrument,presetfile,pluginpresetfile" ); } -void InstrumentTrackWindow::dragEnterEvent( QDragEnterEvent * _dee ) +void InstrumentTrackWindow::dragEnterEvent( QDragEnterEvent* event ) { - dragEnterEventGeneric( _dee ); + dragEnterEventGeneric( event ); } -void InstrumentTrackWindow::dropEvent( QDropEvent * _de ) +void InstrumentTrackWindow::dropEvent( QDropEvent* event ) { - QString type = stringPairDrag::decodeKey( _de ); - QString value = stringPairDrag::decodeValue( _de ); + QString type = stringPairDrag::decodeKey( event ); + QString value = stringPairDrag::decodeValue( event ); + if( type == "instrument" ) { m_track->loadInstrument( value ); + engine::getSong()->setModified(); - _de->accept(); + + event->accept(); } else if( type == "presetfile" ) { @@ -1626,40 +1518,43 @@ void InstrumentTrackWindow::dropEvent( QDropEvent * _de ) InstrumentTrack::removeMidiPortNode( mmp ); m_track->setSimpleSerializing(); m_track->loadSettings( mmp.content().toElement() ); + engine::getSong()->setModified(); - _de->accept(); + + event->accept(); } else if( type == "pluginpresetfile" ) { const QString ext = fileItem::extension( value ); Instrument * i = m_track->instrument(); + if( !i->descriptor()->supportsFileType( ext ) ) { - i = m_track->loadInstrument( - engine::pluginFileHandling()[ext] ); + i = m_track->loadInstrument( engine::pluginFileHandling()[ext] ); } + i->loadFile( value ); - _de->accept(); + + event->accept(); } } -void InstrumentTrackWindow::saveSettings( QDomDocument & _doc, - QDomElement & _this ) +void InstrumentTrackWindow::saveSettings( QDomDocument& doc, QDomElement & thisElement ) { - _this.setAttribute( "tab", m_tabWidget->activeTab() ); - MainWindow::saveWidgetState( this, _this ); + thisElement.setAttribute( "tab", m_tabWidget->activeTab() ); + MainWindow::saveWidgetState( this, thisElement ); } -void InstrumentTrackWindow::loadSettings( const QDomElement & _this ) +void InstrumentTrackWindow::loadSettings( const QDomElement& thisElement ) { - m_tabWidget->setActiveTab( _this.attribute( "tab" ).toInt() ); - MainWindow::restoreWidgetState( this, _this ); + m_tabWidget->setActiveTab( thisElement.attribute( "tab" ).toInt() ); + MainWindow::restoreWidgetState( this, thisElement ); if( isVisible() ) { m_itv->m_tlb->setChecked( true ); diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 9b7e55eedd..25f6eee3b8 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -74,7 +74,7 @@ SampleTCO::~SampleTCO() -void SampleTCO::changeLength( const midiTime & _length ) +void SampleTCO::changeLength( const MidiTime & _length ) { trackContentObject::changeLength( qMax( static_cast( _length ), DefaultTicksPerTact ) ); } @@ -128,7 +128,7 @@ void SampleTCO::updateLength( bpm_t ) -midiTime SampleTCO::sampleLength() const +MidiTime SampleTCO::sampleLength() const { return (int)( m_sampleBuffer->frames() / engine::framesPerTick() ); } @@ -406,7 +406,7 @@ SampleTrack::~SampleTrack() -bool SampleTrack::play( const midiTime & _start, const fpp_t _frames, +bool SampleTrack::play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _offset, int /*_tco_num*/ ) { m_audioPort.effects()->startRunning(); @@ -461,7 +461,7 @@ trackView * SampleTrack::createView( TrackContainerView* tcv ) -trackContentObject * SampleTrack::createTCO( const midiTime & ) +trackContentObject * SampleTrack::createTCO( const MidiTime & ) { return new SampleTCO( this ); } diff --git a/src/tracks/bb_track.cpp b/src/tracks/bb_track.cpp index 67b2c2b59a..a2c041e576 100644 --- a/src/tracks/bb_track.cpp +++ b/src/tracks/bb_track.cpp @@ -55,7 +55,7 @@ bbTCO::bbTCO( track * _track, unsigned int _color ) : if( t > 0 ) { saveJournallingState( false ); - changeLength( midiTime( t, 0 ) ); + changeLength( MidiTime( t, 0 ) ); restoreJournallingState(); } } @@ -192,7 +192,7 @@ void bbTCOView::paintEvent( QPaintEvent * ) tact_t t = engine::getBBTrackContainer()->lengthOfBB( bbTrack::numOfBBTrack( m_bbTCO->getTrack() ) ); - if( m_bbTCO->length() > midiTime::ticksPerTact() && t > 0 ) + if( m_bbTCO->length() > MidiTime::ticksPerTact() && t > 0 ) { for( int x = static_cast( t * pixelsPerTact() ); x < width()-2; @@ -341,7 +341,7 @@ bbTrack::~bbTrack() // play _frames frames of given TCO within starting with _start -bool bbTrack::play( const midiTime & _start, const fpp_t _frames, +bool bbTrack::play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _offset, int _tco_num ) { if( isMuted() ) @@ -362,8 +362,8 @@ bool bbTrack::play( const midiTime & _start, const fpp_t _frames, return false; } - midiTime lastPosition; - midiTime lastLen; + MidiTime lastPosition; + MidiTime lastLen; for( tcoVector::iterator it = tcos.begin(); it != tcos.end(); ++it ) { if( !( *it )->isMuted() && @@ -392,7 +392,7 @@ trackView * bbTrack::createView( TrackContainerView* tcv ) -trackContentObject * bbTrack::createTCO( const midiTime & _pos ) +trackContentObject * bbTrack::createTCO( const MidiTime & _pos ) { // if we're creating a new bbTCO, we colorize it according to the // previous bbTCO, so we have to get all TCOs from 0 to _pos and diff --git a/src/tracks/pattern.cpp b/src/tracks/pattern.cpp index 611f18adca..95ab237aa4 100644 --- a/src/tracks/pattern.cpp +++ b/src/tracks/pattern.cpp @@ -63,7 +63,7 @@ pattern::pattern( InstrumentTrack * _instrument_track ) : trackContentObject( _instrument_track ), m_instrumentTrack( _instrument_track ), m_patternType( BeatPattern ), - m_steps( midiTime::stepsPerTact() ), + m_steps( MidiTime::stepsPerTact() ), m_frozenPattern( NULL ), m_freezing( false ), m_freezeAborted( false ) @@ -127,14 +127,14 @@ void pattern::init() -midiTime pattern::length() const +MidiTime pattern::length() const { if( m_patternType == BeatPattern ) { return beatPatternLength(); } - tick_t max_length = midiTime::ticksPerTact(); + tick_t max_length = MidiTime::ticksPerTact(); for( NoteVector::ConstIterator it = m_notes.begin(); it != m_notes.end(); ++it ) @@ -145,16 +145,16 @@ midiTime pattern::length() const ( *it )->endPos() ); } } - return midiTime( max_length ).nextFullTact() * - midiTime::ticksPerTact(); + return MidiTime( max_length ).nextFullTact() * + MidiTime::ticksPerTact(); } -midiTime pattern::beatPatternLength() const +MidiTime pattern::beatPatternLength() const { - tick_t max_length = midiTime::ticksPerTact(); + tick_t max_length = MidiTime::ticksPerTact(); for( NoteVector::ConstIterator it = m_notes.begin(); it != m_notes.end(); ++it ) @@ -163,18 +163,18 @@ midiTime pattern::beatPatternLength() const { max_length = qMax( max_length, ( *it )->pos() + - midiTime::ticksPerTact() / - midiTime::stepsPerTact() ); + MidiTime::ticksPerTact() / + MidiTime::stepsPerTact() ); } } - if( m_steps != midiTime::stepsPerTact() ) + if( m_steps != MidiTime::stepsPerTact() ) { - max_length = m_steps * midiTime::ticksPerTact() / - midiTime::stepsPerTact() ; + max_length = m_steps * MidiTime::ticksPerTact() / + MidiTime::stepsPerTact() ; } - return midiTime( max_length ).nextFullTact() * midiTime::ticksPerTact(); + return MidiTime( max_length ).nextFullTact() * MidiTime::ticksPerTact(); } @@ -385,7 +385,7 @@ void pattern::loadSettings( const QDomElement & _this ) { movePosition( _this.attribute( "pos" ).toInt() ); } - changeLength( midiTime( _this.attribute( "len" ).toInt() ) ); + changeLength( MidiTime( _this.attribute( "len" ).toInt() ) ); if( _this.attribute( "muted" ).toInt() != isMuted() ) { toggleMute(); @@ -409,7 +409,7 @@ void pattern::loadSettings( const QDomElement & _this ) m_steps = _this.attribute( "steps" ).toInt(); if( m_steps == 0 ) { - m_steps = midiTime::stepsPerTact(); + m_steps = MidiTime::stepsPerTact(); } ensureBeatNotes(); @@ -487,7 +487,7 @@ void pattern::abortFreeze() void pattern::addSteps() { - m_steps += midiTime::stepsPerTact(); + m_steps += MidiTime::stepsPerTact(); ensureBeatNotes(); emit dataChanged(); } @@ -497,7 +497,7 @@ void pattern::addSteps() void pattern::removeSteps() { - int _n = midiTime::stepsPerTact(); + int _n = MidiTime::stepsPerTact(); if( _n < m_steps ) { for( int i = m_steps - _n; i < m_steps; ++i ) @@ -506,8 +506,8 @@ void pattern::removeSteps() it != m_notes.end(); ++it ) { if( ( *it )->pos() == - i * midiTime::ticksPerTact() / - midiTime::stepsPerTact() && + i * MidiTime::ticksPerTact() / + MidiTime::stepsPerTact() && ( *it )->length() <= 0 ) { removeNote( *it ); @@ -542,8 +542,8 @@ void pattern::ensureBeatNotes() it != m_notes.end(); ++it ) { if( ( *it )->pos() == - i * midiTime::ticksPerTact() / - midiTime::stepsPerTact() && + i * MidiTime::ticksPerTact() / + MidiTime::stepsPerTact() && ( *it )->length() <= 0 ) { found = true; @@ -552,9 +552,9 @@ void pattern::ensureBeatNotes() } if( found == false ) { - addNote( note( midiTime( 0 ), midiTime( i * - midiTime::ticksPerTact() / - midiTime::stepsPerTact() ) ), false ); + addNote( note( MidiTime( 0 ), MidiTime( i * + MidiTime::ticksPerTact() / + MidiTime::stepsPerTact() ) ), false ); } } } @@ -591,17 +591,17 @@ bool pattern::empty() void pattern::changeTimeSignature() { - midiTime last_pos = midiTime::ticksPerTact(); + MidiTime last_pos = MidiTime::ticksPerTact(); for( NoteVector::ConstIterator cit = m_notes.begin(); cit != m_notes.end(); ++cit ) { if( ( *cit )->length() < 0 && ( *cit )->pos() > last_pos ) { - last_pos = ( *cit )->pos()+midiTime::ticksPerTact() / - midiTime::stepsPerTact(); + last_pos = ( *cit )->pos()+MidiTime::ticksPerTact() / + MidiTime::stepsPerTact(); } } - last_pos = last_pos.nextFullTact() * midiTime::ticksPerTact(); + last_pos = last_pos.nextFullTact() * MidiTime::ticksPerTact(); for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end(); ) { if( ( *it )->length() == 0 && ( *it )->pos() >= last_pos ) @@ -616,8 +616,8 @@ void pattern::changeTimeSignature() } } m_steps = qMax( - qMax( m_steps, midiTime::stepsPerTact() ), - last_pos.getTact() * midiTime::stepsPerTact() ); + qMax( m_steps, MidiTime::stepsPerTact() ), + last_pos.getTact() * MidiTime::stepsPerTact() ); ensureBeatNotes(); } @@ -970,7 +970,7 @@ void patternView::mouseDoubleClickEvent( QMouseEvent * _me ) if( m_pat->type() == pattern::MelodyPattern || !( m_pat->type() == pattern::BeatPattern && ( pixelsPerTact() >= 192 || - m_pat->m_steps != midiTime::stepsPerTact() ) && + m_pat->m_steps != MidiTime::stepsPerTact() ) && _me->y() > height() - s_stepBtnOff->height() ) ) { openInPianoRoll(); @@ -985,7 +985,7 @@ void patternView::mousePressEvent( QMouseEvent * _me ) if( _me->button() == Qt::LeftButton && m_pat->m_patternType == pattern::BeatPattern && ( fixedTCOs() || pixelsPerTact() >= 96 || - m_pat->m_steps != midiTime::stepsPerTact() ) && + m_pat->m_steps != MidiTime::stepsPerTact() ) && _me->y() > height() - s_stepBtnOff->height() ) { int step = ( _me->x() - TCO_BORDER_WIDTH ) * @@ -1033,7 +1033,7 @@ void patternView::wheelEvent( QWheelEvent * _we ) { if( m_pat->m_patternType == pattern::BeatPattern && ( fixedTCOs() || pixelsPerTact() >= 96 || - m_pat->m_steps != midiTime::stepsPerTact() ) && + m_pat->m_steps != MidiTime::stepsPerTact() ) && _we->y() > height() - s_stepBtnOff->height() ) { int step = ( _we->x() - TCO_BORDER_WIDTH ) * @@ -1192,9 +1192,9 @@ void patternView::paintEvent( QPaintEvent * ) { const int x1 = 2 * x_base + static_cast( ( *it )->pos() * ppt / - midiTime::ticksPerTact() ); + MidiTime::ticksPerTact() ); const int x2 = - static_cast( ( ( *it )->pos() + ( *it )->length() ) * ppt / midiTime::ticksPerTact() ); + static_cast( ( ( *it )->pos() + ( *it )->length() ) * ppt / MidiTime::ticksPerTact() ); p.drawLine( x1, y_base + y_pos, x2, y_base + y_pos ); @@ -1205,7 +1205,7 @@ void patternView::paintEvent( QPaintEvent * ) } else if( m_pat->m_patternType == pattern::BeatPattern && ( fixedTCOs() || ppt >= 96 - || m_pat->m_steps != midiTime::stepsPerTact() ) ) + || m_pat->m_steps != MidiTime::stepsPerTact() ) ) { QPixmap stepon; QPixmap stepoverlay;