diff --git a/.mailmap b/.mailmap new file mode 100644 index 000000000..067e8929c --- /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/.travis.yml b/.travis.yml index 92aa8a9d8..b16a73e8e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,4 @@ compiler: gcc before_install: sudo apt-get update install: sudo apt-get install libqt4-dev libsndfile-dev fftw3-dev libvorbis-dev libogg-dev libasound2-dev libjack-dev libsdl-dev libsamplerate0-dev libstk0-dev libfluidsynth-dev portaudio19-dev wine-dev g++-multilib before_script: mkdir build && cd build -script: cmake .. && make -j8 +script: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. && make -j8 diff --git a/AUTHORS b/AUTHORS index 9bdf47818..22dc31bb9 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 92e5d6b67..b097bf538 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 "") @@ -335,6 +337,7 @@ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/plugins/zynaddsubfx/zynaddsubfx.rc.in ${CMAKE SET(WERROR_FLAGS "-Wall -Werror -Werror=unused-function -Wno-sign-compare -Wno-strict-overflow") SET(CMAKE_C_FLAGS "-O2 -g ${WERROR_FLAGS} ${CMAKE_C_FLAGS}") SET(CMAKE_CXX_FLAGS "-O2 -g -fno-exceptions ${WERROR_FLAGS} ${CMAKE_CXX_FLAGS}") +set(CMAKE_C_FLAGS_DEBUG "-DLMMS_DEBUG") # people simply updating git will still have this and mess up build with it @@ -346,7 +349,19 @@ FILE(GLOB_RECURSE lmms_SOURCES ${CMAKE_SOURCE_DIR}/src/*.cpp) SET(lmms_MOC ${lmms_INCLUDES}) -SET(lmms_EMBEDDED_RESOURCES ${CMAKE_SOURCE_DIR}/AUTHORS ${CMAKE_SOURCE_DIR}/COPYING) +# Get list of all committers from git history, ordered by number of commits +FIND_PACKAGE(Git) +IF(GIT_FOUND) + SET(CONTRIBUTORS ${CMAKE_BINARY_DIR}/CONTRIBUTORS) + EXECUTE_PROCESS( + COMMAND ${GIT_EXECUTABLE} shortlog -sne + COMMAND cut -c8- + OUTPUT_FILE ${CONTRIBUTORS} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + TIMEOUT 1) +ENDIF(GIT_FOUND) + +SET(lmms_EMBEDDED_RESOURCES ${CMAKE_SOURCE_DIR}/AUTHORS ${CMAKE_SOURCE_DIR}/COPYING ${CONTRIBUTORS}) QT4_WRAP_CPP(lmms_MOC_out ${lmms_MOC} OPTIONS -nw) QT4_WRAP_UI(lmms_UI_out ${lmms_UI}) @@ -512,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") @@ -557,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 1b4c1d370..507c1099e 100644 Binary files a/data/lmms.ico and b/data/lmms.ico differ diff --git a/data/locale/ca.ts b/data/locale/ca.ts index 3295f82ec..d0ff53fa9 100644 --- a/data/locale/ca.ts +++ b/data/locale/ca.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave octava @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS ACORDS diff --git a/data/locale/cs.ts b/data/locale/cs.ts index 1118a1643..af6a41d67 100644 --- a/data/locale/cs.ts +++ b/data/locale/cs.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave oktáva @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS AKORDY diff --git a/data/locale/de.ts b/data/locale/de.ts index cdeb4810d..3ee513bcf 100644 --- a/data/locale/de.ts +++ b/data/locale/de.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave Oktave @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS AKKORDE diff --git a/data/locale/en.ts b/data/locale/en.ts index 8ed3172cb..20e29f33f 100644 --- a/data/locale/en.ts +++ b/data/locale/en.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS diff --git a/data/locale/es.ts b/data/locale/es.ts index b0a0e2e90..a986f5af0 100644 --- a/data/locale/es.ts +++ b/data/locale/es.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave Octava @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS diff --git a/data/locale/fa.ts b/data/locale/fa.ts index b84820ea8..2c7fec6d5 100644 --- a/data/locale/fa.ts +++ b/data/locale/fa.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave نت @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS diff --git a/data/locale/fr.ts b/data/locale/fr.ts index 8ca35588f..e45aca6d1 100644 --- a/data/locale/fr.ts +++ b/data/locale/fr.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave octave @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS ACCORDS diff --git a/data/locale/gl.ts b/data/locale/gl.ts index 546ed3698..21d411161 100644 --- a/data/locale/gl.ts +++ b/data/locale/gl.ts @@ -501,7 +501,7 @@ Se lle interesa traducir o LMMS a outro idioma ou desexa mellorar as traducións - ChordCreator + InstrumentFunctionNoteStacking octave oitava @@ -872,7 +872,7 @@ Se lle interesa traducir o LMMS a outro idioma ou desexa mellorar as traducións - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS ACORDES diff --git a/data/locale/it.ts b/data/locale/it.ts index 95df96983..ccbac12ec 100644 --- a/data/locale/it.ts +++ b/data/locale/it.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave ottava @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS ACCORDI diff --git a/data/locale/ja.ts b/data/locale/ja.ts index 275e35a97..fe1255193 100644 --- a/data/locale/ja.ts +++ b/data/locale/ja.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS diff --git a/data/locale/ko.ts b/data/locale/ko.ts index 584eb9eb5..a18db80cf 100644 --- a/data/locale/ko.ts +++ b/data/locale/ko.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave 옥타브 @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS diff --git a/data/locale/nl.ts b/data/locale/nl.ts index de0acab03..a1c52d034 100644 --- a/data/locale/nl.ts +++ b/data/locale/nl.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave oktaaf @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS AKKOORDEN diff --git a/data/locale/pl.ts b/data/locale/pl.ts index f3d438f20..0f399180c 100644 --- a/data/locale/pl.ts +++ b/data/locale/pl.ts @@ -494,7 +494,7 @@ Zauważone błędy i propozycje zmian tłumaczenia proszę zgłaszać na e-mail: - ChordCreator + InstrumentFunctionNoteStacking octave @@ -861,7 +861,7 @@ Zauważone błędy i propozycje zmian tłumaczenia proszę zgłaszać na e-mail: - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS AKORDY diff --git a/data/locale/pt_br.ts b/data/locale/pt_br.ts index 1ea74f00c..c01038992 100644 --- a/data/locale/pt_br.ts +++ b/data/locale/pt_br.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave oitava @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS ACORDE diff --git a/data/locale/ru.ts b/data/locale/ru.ts index d55cdfc58..90ac1ea1c 100644 --- a/data/locale/ru.ts +++ b/data/locale/ru.ts @@ -492,7 +492,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave Октава @@ -859,7 +859,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS АККОРД diff --git a/data/locale/sv.ts b/data/locale/sv.ts index 1e1749a4e..1cd1b56c5 100644 --- a/data/locale/sv.ts +++ b/data/locale/sv.ts @@ -488,7 +488,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreator + InstrumentFunctionNoteStacking octave oktav @@ -855,7 +855,7 @@ If you're interested in translating LMMS in another language or want to imp - ChordCreatorView + InstrumentFunctionNoteStackingView CHORDS diff --git a/data/nsis_branding.bmp b/data/nsis_branding.bmp index 94691eb51..901497e2c 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 000000000..15aae06ac --- /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 000000000..aade9bd6c --- /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 000000000..f995fb96e --- /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 000000000..bf4d925af --- /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 000000000..d30fce903 --- /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 000000000..ec3357c53 --- /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 000000000..92550e15c --- /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 000000000..cbfa3ea9a --- /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 000000000..e1c2baa47 --- /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 000000000..d3769abe2 --- /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 000000000..e5c686d93 --- /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 000000000..9f46ffed0 --- /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 000000000..636ce3628 --- /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 000000000..8c40992e4 --- /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 000000000..b41cd40e6 --- /dev/null +++ b/data/presets/OpulenZ/Vibraphone.xpf @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/data/projects/CoolSongs/Greippi-ardudar.mmpz b/data/projects/CoolSongs/Greippi-ardudar.mmpz new file mode 100644 index 000000000..17ff90dfd Binary files /dev/null and b/data/projects/CoolSongs/Greippi-ardudar.mmpz differ diff --git a/data/projects/CoolSongs/LICENSES.TXT b/data/projects/CoolSongs/LICENSES.TXT index f97d85007..cf4877625 100644 --- a/data/projects/CoolSongs/LICENSES.TXT +++ b/data/projects/CoolSongs/LICENSES.TXT @@ -13,11 +13,19 @@ * Farbro-Tectonic.mmpz - CC (by) - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1327 + +* Greippi-ardudar.mmpz + - CC (by-sa) + - http://lmms.sourceforge.net/lsp/index.php?action=show&file=4916 * Impulslogik-Zen.mmpz - 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 @@ -54,6 +62,14 @@ - 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) + - http://lmms.sourceforge.net/lsp/index.php?action=show&file=4929 + * Zakarra-MainstreamMemory.mmpz - Artistic 2.0 - http://lmms.sourceforge.net/lsp/index.php?action=show&file=1201 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/CoolSongs/unfa-Spoken.mmpz b/data/projects/CoolSongs/unfa-Spoken.mmpz new file mode 100644 index 000000000..35c5c4b24 Binary files /dev/null and b/data/projects/CoolSongs/unfa-Spoken.mmpz differ diff --git a/data/projects/Covers/CapDan-Infinity2010.mmpz b/data/projects/Covers/CapDan-Infinity2010.mmpz deleted file mode 100644 index 08b8705d9..000000000 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 61d5856e8..000000000 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 066f1e881..000000000 --- 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 c76c8ee32..000000000 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 e029787c7..f79fdfdba 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 000000000..f4e79fb4d 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 f547bf179..1ae48682e 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 b0ce4a5cc..85586f7da 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 78e7ad37f..07a4ecc7e 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 f72c0c940..513331df7 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 d6193e4f6..a7480fd70 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 c0a4f37c8..a2d56e672 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 29da5c1dc..8c4bb5690 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 5eb2c12bc..d8b8b73fe 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 b89c2107a..dfde88b4e 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 155664925..a26017741 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 000000000..515e9711c 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 8aa83cdbe..42165f6b0 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 92430c252..83bdb4140 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 e0f4a1581..f05db1a06 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 cbb3bd478..900cd5b46 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 21a0cab62..3924a9173 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 5019cd89a..11b674a60 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 48b4b5a89..22682a150 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 647e75338..84051dbb6 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 2753bc352..0247da592 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 060297da2..561fead25 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 f2a05b555..bb966c579 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 479ff38c1..cb563f432 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 3a44b3e28..2c54a6ab1 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 9a530a1b3..f6230f6d4 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 f81425dae..9e80341e0 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 4b1e934bd..f55150f46 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 f81425dae..f7cac8689 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 aff73e593..1444bcf11 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 6c3acf2cd..acd47baab 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 661bcb7be..44c900ceb 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 a3daee579..204325edc 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 4e4d214de..3cd7ea452 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 5c8a7e90c..a2c80fe19 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 39c037b2a..029a50300 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 a307b542a..31ce41942 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 20e2ab65a..9f8b31122 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 f178b5023..36c2308b9 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 b1405a63b..46ec86d44 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 c9b45d7d9..04725f997 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 eea2cf9b6..ee66b4929 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 b7cff0117..5ba9bc3c9 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 c9897ae40..53a0d1159 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 db0fe6e1f..724ab5cfb 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 125107958..fc1d435d3 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 0dbbb91b9..7dd091a12 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 699153a93..c92882ecd 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 b2d794d39..0dfe2093a 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 30814a1b9..f2ed8d46e 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 754146f3e..4df4ca8e1 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 648910b6b..62bffcc33 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 fa680ab76..4b6e1427f 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 57e06d408..ec7bf0a7d 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 a79a22b98..487b5aff7 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 4e64f396c..2d204586a 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 0d199ba12..94a4b393c 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; @@ -472,6 +533,14 @@ sf2InstrumentView knob { qproperty-lineWidth: 2; } +sfxrInstrumentView knob { + color: #b06319; + qproperty-outerColor: rgb(194, 177, 145); + qproperty-innerRadius: 2; + qproperty-outerRadius: 10; + qproperty-lineWidth: 2; +} + opl2instrumentView knob { color: rgb(128,128,128); qproperty-outerColor: rgb(255,255,255); @@ -494,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 dcb8036e2..bc089652e 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 fbd6343dd..418e4f8eb 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 df1ad5642..b88839a0d 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 79a4c6807..f3ef94abc 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 336ca87c6..2309967d5 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 8c8fa9d7f..38b089c63 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 d725366a4..1e37cd9b4 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 8b11c332c..ea20bb3a0 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 834174ece..a4c44b302 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 new file mode 100644 index 000000000..f4d81ea3d --- /dev/null +++ b/include/FileDialog.h @@ -0,0 +1,44 @@ +/* + * FileDialog.h - declaration of class FileDialog + * + * Copyright (c) 2014 Lukas W + * + * 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 FILEDIALOG_H +#define FILEDIALOG_H + +#include + +#include "export.h" + +class EXPORT FileDialog : public QFileDialog +{ + Q_OBJECT +public: + explicit FileDialog( QWidget *parent = 0, const QString &caption = QString(), + const QString &directory = QString(), + const QString &filter = QString() ); + + void clearSelection(); +}; + +#endif // FILEDIALOG_HPP diff --git a/include/Instrument.h b/include/Instrument.h index 7cec41019..0a840daa3 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/InstrumentFunctionViews.h b/include/InstrumentFunctionViews.h index 3b4334147..2a370468a 100644 --- a/include/InstrumentFunctionViews.h +++ b/include/InstrumentFunctionViews.h @@ -1,7 +1,7 @@ /* * InstrumentFunctionViews.h - views for instrument-functions-tab * - * 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,23 +35,23 @@ class groupBox; class knob; class TempoSyncKnob; -class Arpeggiator; -class ChordCreator; +class InstrumentFunctionArpeggio; +class InstrumentFunctionNoteStacking; -class ChordCreatorView : public QWidget, public ModelView +class InstrumentFunctionNoteStackingView : public QWidget, public ModelView { Q_OBJECT public: - ChordCreatorView( ChordCreator * _cc, QWidget * _parent ); - virtual ~ChordCreatorView(); + InstrumentFunctionNoteStackingView( InstrumentFunctionNoteStacking* cc, QWidget* parent = NULL ); + virtual ~InstrumentFunctionNoteStackingView(); private: virtual void modelChanged(); - ChordCreator * m_cc; + InstrumentFunctionNoteStacking * m_cc; groupBox * m_chordsGroupBox; comboBox * m_chordsComboBox; @@ -63,26 +63,24 @@ private: -class ArpeggiatorView : public QWidget, public ModelView +class InstrumentFunctionArpeggioView : public QWidget, public ModelView { Q_OBJECT public: - ArpeggiatorView( Arpeggiator * _arp, QWidget * _parent ); - virtual ~ArpeggiatorView(); + InstrumentFunctionArpeggioView( InstrumentFunctionArpeggio* arp, QWidget* parent = NULL ); + virtual ~InstrumentFunctionArpeggioView(); private: virtual void modelChanged(); - Arpeggiator * m_a; + InstrumentFunctionArpeggio * m_a; groupBox * m_arpGroupBox; comboBox * m_arpComboBox; knob * m_arpRangeKnob; TempoSyncKnob * m_arpTimeKnob; knob * m_arpGateKnob; - QLabel * m_arpDirectionLbl; - comboBox * m_arpDirectionComboBox; comboBox * m_arpModeComboBox; diff --git a/include/InstrumentFunctions.h b/include/InstrumentFunctions.h index b26460494..14b1ae618 100644 --- a/include/InstrumentFunctions.h +++ b/include/InstrumentFunctions.h @@ -37,7 +37,7 @@ class notePlayHandle; -class ChordCreator : public Model, public JournallingObject +class InstrumentFunctionNoteStacking : public Model, public JournallingObject { Q_OBJECT @@ -48,8 +48,8 @@ private: typedef int8_t ChordSemiTones [MAX_CHORD_POLYPHONY]; public: - ChordCreator( Model * _parent ); - virtual ~ChordCreator(); + InstrumentFunctionNoteStacking( Model * _parent ); + virtual ~InstrumentFunctionNoteStacking(); void processNote( notePlayHandle * _n ); @@ -149,14 +149,14 @@ private: FloatModel m_chordRangeModel; - friend class ChordCreatorView; + friend class InstrumentFunctionNoteStackingView; } ; -class Arpeggiator : public Model, public JournallingObject +class InstrumentFunctionArpeggio : public Model, public JournallingObject { Q_OBJECT public: @@ -169,8 +169,8 @@ public: NumArpDirections } ; - Arpeggiator( Model * _parent ); - virtual ~Arpeggiator(); + InstrumentFunctionArpeggio( Model * _parent ); + virtual ~InstrumentFunctionArpeggio(); void processNote( notePlayHandle * _n ); @@ -203,7 +203,7 @@ private: friend class FlpImport; friend class InstrumentTrack; - friend class ArpeggiatorView; + friend class InstrumentFunctionArpeggioView; } ; diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 7df268b82..d4ca720c3 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -34,13 +34,14 @@ #include "note_play_handle.h" #include "Piano.h" #include "PianoView.h" +#include "Pitch.h" #include "track.h" class QLineEdit; template class QQueue; -class ArpeggiatorView; -class ChordCreatorView; +class InstrumentFunctionArpeggioView; +class InstrumentFunctionNoteStackingView; class EffectRackView; class InstrumentSoundShapingView; class fadeButton; @@ -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 @@ -162,9 +167,9 @@ public: return &m_piano; } - bool isArpeggiatorEnabled() const + bool isArpeggioEnabled() const { - return m_arpeggiator.m_arpEnabledModel.value(); + return m_arpeggio.m_arpEnabledModel.value(); } // simple helper for removing midiport-XML-node when loading presets @@ -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(); @@ -238,8 +243,8 @@ private: Instrument * m_instrument; InstrumentSoundShaping m_soundShaping; - Arpeggiator m_arpeggiator; - ChordCreator m_chordCreator; + InstrumentFunctionArpeggio m_arpeggio; + InstrumentFunctionNoteStacking m_noteStacking; Piano m_piano; @@ -402,8 +407,8 @@ private: tabWidget * m_tabWidget; PluginView * m_instrumentView; InstrumentSoundShapingView * m_ssView; - ChordCreatorView * m_chordView; - ArpeggiatorView * m_arpView; + InstrumentFunctionNoteStackingView* m_noteStackingView; + InstrumentFunctionArpeggioView* m_arpeggioView; InstrumentMidiIOView * m_midiView; EffectRackView * m_effectView; diff --git a/include/LfoController.h b/include/LfoController.h index 45118e9e1..59bea8689 100644 --- a/include/LfoController.h +++ b/include/LfoController.h @@ -75,6 +75,8 @@ protected: sample_t (*m_sampleFunction)( const float ); +private: + SampleBuffer * m_userDefSampleBuffer; protected slots: void updateSampleFunction(); @@ -107,6 +109,13 @@ protected: automatableButtonGroup * m_waveBtnGrp; automatableButtonGroup * m_multiplierBtnGrp; + +private: + pixmapButton * m_userWaveBtn; + +private slots: + void askUserDefWave(); + } ; #endif diff --git a/include/MainWindow.h b/include/MainWindow.h index 6335c6401..8a10f1351 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -102,6 +102,7 @@ public slots: void openProject( void ); bool saveProject( void ); bool saveProjectAs( void ); + bool saveProjectAsNewVersion( void ); void showSettingsDialog( void ); void aboutLMMS( void ); void help( void ); diff --git a/include/midi.h b/include/Midi.h similarity index 53% rename from include/midi.h rename to include/Midi.h index 09a9afa1b..1b6b69383 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 13d250c3f..70640ae3a 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 b8f0b459a..2888999ac 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 f9d3a0d33..2271e8659 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 000000000..38bf33f90 --- /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 1b3d0dd33..dafcfb6cd 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 a5b1aee0e..767dc932e 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 f7f857624..9a86f3b48 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 51cccae71..54b6bdf0d 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 000000000..dc479857e --- /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 46ffc5e15..8eb097ebd 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/SampleBuffer.h b/include/SampleBuffer.h index cd5a243e1..e42d3690e 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -172,7 +172,8 @@ public: return m_data; } - QString openAudioFile() const; + QString openAudioFile() const; + QString openAndSetAudioFile(); QString & toBase64( QString & _dst ) const; diff --git a/include/SampleRecordHandle.h b/include/SampleRecordHandle.h index 465005fbe..6ff8a3d63 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 975ba2477..fed785657 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/TempoSyncKnob.h b/include/TempoSyncKnob.h index 6f54089f0..964d77cf4 100644 --- a/include/TempoSyncKnob.h +++ b/include/TempoSyncKnob.h @@ -2,7 +2,7 @@ * TempoSyncKnob.h - adds bpm to ms conversion for knob class * * Copyright (c) 2005-2008 Danny McRae - * Copyright (c) 2009 Tobias Doerffel + * Copyright (c) 2009-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -38,8 +38,7 @@ class EXPORT TempoSyncKnob : public knob { Q_OBJECT public: - TempoSyncKnob( int _knob_num, QWidget * _parent, - const QString & _name = QString() ); + TempoSyncKnob( int knobNum, QWidget* parent = NULL, const QString& name = QString() ); virtual ~TempoSyncKnob(); const QString & syncDescription(); diff --git a/include/TrackContainerView.h b/include/TrackContainerView.h index 2203fb868..a18bf5a78 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/VersionedSaveDialog.h b/include/VersionedSaveDialog.h new file mode 100644 index 000000000..8041f00f1 --- /dev/null +++ b/include/VersionedSaveDialog.h @@ -0,0 +1,53 @@ +/* + * VersionedSaveDialog.h - declaration of class VersionedSaveDialog, a file save + * dialog that provides buttons to increment or decrement a version which is + * appended to the file name. (e.g. "MyProject-01.mmpz") + * + * Copyright (c) 2014 Lukas W + * + * 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 VERSIONEDSAVEDIALOG_H +#define VERSIONEDSAVEDIALOG_H + +#include "FileDialog.h" + +class QLineEdit; + + +class VersionedSaveDialog : public FileDialog +{ + Q_OBJECT +public: + explicit VersionedSaveDialog( QWidget *parent = 0, + const QString &caption = QString(), + const QString &directory = QString(), + const QString &filter = QString() ); + + // Returns true if file name was changed, returns false if it wasn't + static bool changeFileNameVersion( QString &fileName, bool increment ); + +public slots: + void incrementVersion(); + void decrementVersion(); +}; + +#endif // VERSIONEDSAVEDIALOG_H diff --git a/include/aeffectx.h b/include/aeffectx.h index 393249b03..4188bf41a 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 8b0dbff99..a4c440f4c 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 bc9bf7064..3ad0b9157 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/combobox.h b/include/combobox.h index d4d432640..76bb36163 100644 --- a/include/combobox.h +++ b/include/combobox.h @@ -1,7 +1,7 @@ /* - * combobox.h - class comboBox, a very cool combo-box + * combobox.h - class ComboBox, a combo box view for models * - * Copyright (c) 2006-2008 Tobias Doerffel + * Copyright (c) 2006-2014 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -38,31 +38,33 @@ class EXPORT comboBox : public QWidget, public IntModelView { Q_OBJECT public: - comboBox( QWidget * _parent, const QString & _name = QString() ); + comboBox( QWidget* parent = NULL, const QString& name = QString() ); virtual ~comboBox(); - ComboBoxModel * model() + ComboBoxModel* model() { - return( castModel() ); + return castModel(); } - const ComboBoxModel * model() const + const ComboBoxModel* model() const { - return( castModel() ); + return castModel(); } + virtual QSize sizeHint() const; + protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void paintEvent( QPaintEvent * _pe ); - virtual void wheelEvent( QWheelEvent * _we ); + virtual void contextMenuEvent( QContextMenuEvent* event ); + virtual void mousePressEvent( QMouseEvent* event ); + virtual void paintEvent( QPaintEvent* event ); + virtual void wheelEvent( QWheelEvent* event ); private: - static QPixmap * s_background; - static QPixmap * s_arrow; - static QPixmap * s_arrowSelected; + static QPixmap* s_background; + static QPixmap* s_arrow; + static QPixmap* s_arrowSelected; QMenu m_menu; @@ -70,7 +72,7 @@ private: private slots: - void setItem( QAction * _item ); + void setItem( QAction* item ); } ; diff --git a/include/debug.h b/include/debug.h index 1b2b3b2bc..64b1a8886 100644 --- a/include/debug.h +++ b/include/debug.h @@ -31,10 +31,12 @@ // set whether debug-stuff (like messages on the console, asserts and other // additional range-checkings) should be compiled -/*#ifdef LMMS_DEBUG*/ -#include +#ifdef LMMS_DEBUG + #include +#else + #define assert(x) ((void)(x)) +#endif #include -/*#endif*/ #endif diff --git a/include/graph.h b/include/graph.h index 9be552f33..20437996e 100644 --- a/include/graph.h +++ b/include/graph.h @@ -151,7 +151,7 @@ public slots: void setWaveToSaw(); void setWaveToSquare(); void setWaveToNoise(); - //void setWaveToUser( ); + QString setWaveToUser( ); void smooth(); void normalize(); diff --git a/include/knob.h b/include/knob.h index c2e6873f6..b459663b2 100644 --- a/include/knob.h +++ b/include/knob.h @@ -60,7 +60,7 @@ class EXPORT knob : public QWidget, public FloatModelView Q_PROPERTY(QColor outerColor READ outerColor WRITE setOuterColor) mapPropertyFromModel(bool,isVolumeKnob,setVolumeKnob,m_volumeKnob); public: - knob( int _knob_num, QWidget * _parent, const QString & _name = QString() ); + knob( int _knob_num, QWidget * _parent = NULL, const QString & _name = QString() ); virtual ~knob(); // TODO: remove diff --git a/include/note.h b/include/note.h index 36bf1640d..199254f9d 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 2c2b2e3f1..9c22eea3b 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 29d2e5365..60188e3f8 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 26b51849e..fcb66fed9 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 55e193b99..596a29f1a 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 e5185cfbe..abef2c78b 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, diff --git a/include/setup_dialog.h b/include/setup_dialog.h index f5bd00676..53c2be08f 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 58536ba25..5900c8c93 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 989636790..af10cd51c 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 298f42a7b..ff4661837 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 cbb5faaeb..e30e62e48 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 aeb1daf1c..dedecd504 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/CMakeLists.txt b/plugins/CMakeLists.txt index 0cbdc4359..6f315b792 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -15,6 +15,7 @@ ADD_SUBDIRECTORY(papu) ADD_SUBDIRECTORY(patman) ADD_SUBDIRECTORY(peak_controller_effect) ADD_SUBDIRECTORY(sf2_player) +ADD_SUBDIRECTORY(sfxr) ADD_SUBDIRECTORY(sid) ADD_SUBDIRECTORY(spectrum_analyzer) ADD_SUBDIRECTORY(stereo_enhancer) diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index df588eeb4..080c424f3 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -243,7 +243,7 @@ void bitInvader::normalize() const float f = fabsf( samples[i] ); if (f > max) { max = f; } } - normalizeFactor = 1.0 / max; + m_normalizeFactor = 1.0 / max; } @@ -270,7 +270,7 @@ void bitInvader::playNote( notePlayHandle * _n, } else { - factor = normalizeFactor; + factor = m_normalizeFactor; } _n->m_pluginData = new bSynth( @@ -350,69 +350,69 @@ bitInvaderView::bitInvaderView( Instrument * _instrument, m_graph->setPalette( pal ); - sinWaveBtn = new pixmapButton( this, tr( "Sine wave" ) ); - sinWaveBtn->move( 188, 120 ); - sinWaveBtn->setActiveGraphic( embed::getIconPixmap( + m_sinWaveBtn = new pixmapButton( this, tr( "Sine wave" ) ); + m_sinWaveBtn->move( 188, 120 ); + m_sinWaveBtn->setActiveGraphic( embed::getIconPixmap( "sin_wave_active" ) ); - sinWaveBtn->setInactiveGraphic( embed::getIconPixmap( + m_sinWaveBtn->setInactiveGraphic( embed::getIconPixmap( "sin_wave_inactive" ) ); - toolTip::add( sinWaveBtn, + toolTip::add( m_sinWaveBtn, tr( "Click for a sine-wave." ) ); - triangleWaveBtn = new pixmapButton( this, tr( "Triangle wave" ) ); - triangleWaveBtn->move( 188, 136 ); - triangleWaveBtn->setActiveGraphic( + m_triangleWaveBtn = new pixmapButton( this, tr( "Triangle wave" ) ); + m_triangleWaveBtn->move( 188, 136 ); + m_triangleWaveBtn->setActiveGraphic( embed::getIconPixmap( "triangle_wave_active" ) ); - triangleWaveBtn->setInactiveGraphic( + m_triangleWaveBtn->setInactiveGraphic( embed::getIconPixmap( "triangle_wave_inactive" ) ); - toolTip::add( triangleWaveBtn, + toolTip::add( m_triangleWaveBtn, tr( "Click here for a triangle-wave." ) ); - sawWaveBtn = new pixmapButton( this, tr( "Saw wave" ) ); - sawWaveBtn->move( 188, 152 ); - sawWaveBtn->setActiveGraphic( embed::getIconPixmap( + m_sawWaveBtn = new pixmapButton( this, tr( "Saw wave" ) ); + m_sawWaveBtn->move( 188, 152 ); + m_sawWaveBtn->setActiveGraphic( embed::getIconPixmap( "saw_wave_active" ) ); - sawWaveBtn->setInactiveGraphic( embed::getIconPixmap( + m_sawWaveBtn->setInactiveGraphic( embed::getIconPixmap( "saw_wave_inactive" ) ); - toolTip::add( sawWaveBtn, + toolTip::add( m_sawWaveBtn, tr( "Click here for a saw-wave." ) ); - sqrWaveBtn = new pixmapButton( this, tr( "Square wave" ) ); - sqrWaveBtn->move( 188, 168 ); - sqrWaveBtn->setActiveGraphic( embed::getIconPixmap( + m_sqrWaveBtn = new pixmapButton( this, tr( "Square wave" ) ); + m_sqrWaveBtn->move( 188, 168 ); + m_sqrWaveBtn->setActiveGraphic( embed::getIconPixmap( "square_wave_active" ) ); - sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap( + m_sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap( "square_wave_inactive" ) ); - toolTip::add( sqrWaveBtn, + toolTip::add( m_sqrWaveBtn, tr( "Click here for a square-wave." ) ); - whiteNoiseWaveBtn = new pixmapButton( this, + m_whiteNoiseWaveBtn = new pixmapButton( this, tr( "White noise wave" ) ); - whiteNoiseWaveBtn->move( 188, 184 ); - whiteNoiseWaveBtn->setActiveGraphic( + m_whiteNoiseWaveBtn->move( 188, 184 ); + m_whiteNoiseWaveBtn->setActiveGraphic( embed::getIconPixmap( "white_noise_wave_active" ) ); - whiteNoiseWaveBtn->setInactiveGraphic( + m_whiteNoiseWaveBtn->setInactiveGraphic( embed::getIconPixmap( "white_noise_wave_inactive" ) ); - toolTip::add( whiteNoiseWaveBtn, + toolTip::add( m_whiteNoiseWaveBtn, tr( "Click here for white-noise." ) ); - usrWaveBtn = new pixmapButton( this, tr( "User defined wave" ) ); - usrWaveBtn->move( 188, 200 ); - usrWaveBtn->setActiveGraphic( embed::getIconPixmap( + m_usrWaveBtn = new pixmapButton( this, tr( "User defined wave" ) ); + m_usrWaveBtn->move( 188, 200 ); + m_usrWaveBtn->setActiveGraphic( embed::getIconPixmap( "usr_wave_active" ) ); - usrWaveBtn->setInactiveGraphic( embed::getIconPixmap( + m_usrWaveBtn->setInactiveGraphic( embed::getIconPixmap( "usr_wave_inactive" ) ); - toolTip::add( usrWaveBtn, + toolTip::add( m_usrWaveBtn, tr( "Click here for a user-defined shape." ) ); - smoothBtn = new pixmapButton( this, tr( "Smooth" ) ); - smoothBtn->move( 35, 200 ); - smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( + m_smoothBtn = new pixmapButton( this, tr( "Smooth" ) ); + m_smoothBtn->move( 35, 200 ); + m_smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "smooth" ) ); - smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( + m_smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "smooth" ) ); - smoothBtn->setChecked( true ); - toolTip::add( smoothBtn, + m_smoothBtn->setChecked( true ); + toolTip::add( m_smoothBtn, tr( "Click here to smooth waveform." ) ); @@ -426,20 +426,20 @@ bitInvaderView::bitInvaderView( Instrument * _instrument, m_normalizeToggle->move( 55, 100 ); - connect( sinWaveBtn, SIGNAL (clicked () ), + connect( m_sinWaveBtn, SIGNAL (clicked () ), this, SLOT ( sinWaveClicked() ) ); - connect( triangleWaveBtn, SIGNAL ( clicked () ), + connect( m_triangleWaveBtn, SIGNAL ( clicked () ), this, SLOT ( triangleWaveClicked() ) ); - connect( sawWaveBtn, SIGNAL (clicked () ), + connect( m_sawWaveBtn, SIGNAL (clicked () ), this, SLOT ( sawWaveClicked() ) ); - connect( sqrWaveBtn, SIGNAL ( clicked () ), + connect( m_sqrWaveBtn, SIGNAL ( clicked () ), this, SLOT ( sqrWaveClicked() ) ); - connect( whiteNoiseWaveBtn, SIGNAL ( clicked () ), + connect( m_whiteNoiseWaveBtn, SIGNAL ( clicked () ), this, SLOT ( noiseWaveClicked() ) ); - connect( usrWaveBtn, SIGNAL ( clicked () ), + connect( m_usrWaveBtn, SIGNAL ( clicked () ), this, SLOT ( usrWaveClicked() ) ); - connect( smoothBtn, SIGNAL ( clicked () ), + connect( m_smoothBtn, SIGNAL ( clicked () ), this, SLOT ( smoothClicked() ) ); connect( m_interpolationToggle, SIGNAL( toggled( bool ) ), @@ -514,6 +514,9 @@ void bitInvaderView::noiseWaveClicked() void bitInvaderView::usrWaveClicked() { + QString fileName = m_graph->model()->setWaveToUser(); + toolTip::add( m_usrWaveBtn, fileName ); + engine::getSong()->setModified(); /* m_graph->model()->setWaveToNoise(); engine::getSong()->setModified(); diff --git a/plugins/bit_invader/bit_invader.h b/plugins/bit_invader/bit_invader.h index c38eb6b41..7a3217b47 100644 --- a/plugins/bit_invader/bit_invader.h +++ b/plugins/bit_invader/bit_invader.h @@ -99,7 +99,7 @@ private: BoolModel m_interpolation; BoolModel m_normalize; - float normalizeFactor; + float m_normalizeFactor; oscillator * m_osc; @@ -136,13 +136,13 @@ private: virtual void modelChanged(); knob * m_sampleLengthKnob; - pixmapButton * sinWaveBtn; - pixmapButton * triangleWaveBtn; - pixmapButton * sqrWaveBtn; - pixmapButton * sawWaveBtn; - pixmapButton * whiteNoiseWaveBtn; - pixmapButton * smoothBtn; - pixmapButton * usrWaveBtn; + pixmapButton * m_sinWaveBtn; + pixmapButton * m_triangleWaveBtn; + pixmapButton * m_sqrWaveBtn; + pixmapButton * m_sawWaveBtn; + pixmapButton * m_whiteNoiseWaveBtn; + pixmapButton * m_smoothBtn; + pixmapButton * m_usrWaveBtn; static QPixmap * s_artwork; diff --git a/plugins/flp_import/FlpImport.cpp b/plugins/flp_import/FlpImport.cpp index 63f0dc881..c238fee10 100644 --- a/plugins/flp_import/FlpImport.cpp +++ b/plugins/flp_import/FlpImport.cpp @@ -1,5 +1,5 @@ /* - * flp_import.cpp - support for importing FLP-files + * FlpImport.cpp - support for importing FLP-files * * Copyright (c) 2006-2014 Tobias Doerffel * @@ -464,7 +464,7 @@ struct FL_Channel : public FL_Plugin filterCut( 10000 ), filterRes( 0.1 ), filterEnabled( false ), - arpDir( Arpeggiator::ArpDirUp ), + arpDir( InstrumentFunctionArpeggio::ArpDirUp ), arpRange( 0 ), selectedArp( 0 ), arpTime( 100 ), @@ -603,14 +603,14 @@ bool FlpImport::tryImport( TrackContainer* tc ) basicFilters<>::NumFilters+basicFilters<>::LowPass } ; - const Arpeggiator::ArpDirections mappedArpDir[] = + const InstrumentFunctionArpeggio::ArpDirections mappedArpDir[] = { - Arpeggiator::ArpDirUp, - Arpeggiator::ArpDirUp, - Arpeggiator::ArpDirDown, - Arpeggiator::ArpDirUpAndDown, - Arpeggiator::ArpDirUpAndDown, - Arpeggiator::ArpDirRandom + InstrumentFunctionArpeggio::ArpDirUp, + InstrumentFunctionArpeggio::ArpDirUp, + InstrumentFunctionArpeggio::ArpDirDown, + InstrumentFunctionArpeggio::ArpDirUpAndDown, + InstrumentFunctionArpeggio::ArpDirUpAndDown, + InstrumentFunctionArpeggio::ArpDirRandom } ; QMap mappedPluginTypes; @@ -1519,7 +1519,7 @@ else } } - Arpeggiator * arp = &t->m_arpeggiator; + InstrumentFunctionArpeggio * arp = &t->m_arpeggio; arp->m_arpDirectionModel.setValue( it->arpDir ); arp->m_arpRangeModel.setValue( it->arpRange ); arp->m_arpModel.setValue( it->selectedArp ); @@ -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 76a7b2634..f232840fa 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 85621c5dc..5a3e3d0e4 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 b2d05218d..9524d0e87 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 000000000..086faffb5 --- /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 585c2f5eb..0444ce51a 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 47ad49486..66b839334 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/midi_import/portsmf/allegro.cpp b/plugins/midi_import/portsmf/allegro.cpp index d193a3c9d..c05f279e9 100644 --- a/plugins/midi_import/portsmf/allegro.cpp +++ b/plugins/midi_import/portsmf/allegro.cpp @@ -9,7 +9,7 @@ 04 apr 03 -- fixed bug in add_track that caused infinite loop */ -#include "assert.h" +#include "debug.h" #include "stdlib.h" #include "stdio.h" #include "string.h" @@ -727,8 +727,8 @@ void Alg_event_list::set_start_time(Alg_event *event, double t) // For Alg_track, change the time and move the event to the right place // For Alg_seq, find the track and do the update there - long index, i; - Alg_track_ptr track_ptr; + long index = 0, i; + Alg_track_ptr track_ptr = Alg_track_ptr(); if (type == 'e') { // this is an Alg_event_list // make sure the owner has not changed its event set assert(events_owner && @@ -2283,6 +2283,7 @@ Alg_track_ptr Alg_seq::track(int i) } +#pragma GCC diagnostic ignored "-Wreturn-type" // ok not to return a value here Alg_event_ptr &Alg_seq::operator[](int i) { int ntracks = track_list.length(); @@ -2296,7 +2297,7 @@ Alg_event_ptr &Alg_seq::operator[](int i) } tr++; } - assert(false); // out of bounds + assert(false); // out of bounds } diff --git a/plugins/midi_import/portsmf/allegro.h b/plugins/midi_import/portsmf/allegro.h index 51a7b29c0..e83d4b463 100644 --- a/plugins/midi_import/portsmf/allegro.h +++ b/plugins/midi_import/portsmf/allegro.h @@ -48,7 +48,7 @@ #ifndef __ALLEGRO__ #define __ALLEGRO__ -#include +#include "debug.h" #include "lmmsconfig.h" diff --git a/plugins/midi_import/portsmf/allegrord.cpp b/plugins/midi_import/portsmf/allegrord.cpp index 9d6b9f2c1..7a1f5beed 100644 --- a/plugins/midi_import/portsmf/allegrord.cpp +++ b/plugins/midi_import/portsmf/allegrord.cpp @@ -1,4 +1,4 @@ -#include "assert.h" +#include "debug.h" #include "stdlib.h" #include "string.h" #include "ctype.h" diff --git a/plugins/midi_import/portsmf/allegrosmfrd.cpp b/plugins/midi_import/portsmf/allegrosmfrd.cpp index 813ecd79f..49e2ef03e 100644 --- a/plugins/midi_import/portsmf/allegrosmfrd.cpp +++ b/plugins/midi_import/portsmf/allegrosmfrd.cpp @@ -3,7 +3,7 @@ #include "stdlib.h" #include "stdio.h" #include "string.h" -#include "assert.h" +#include "debug.h" #include #include #include "allegro.h" diff --git a/plugins/midi_import/portsmf/allegrowr.cpp b/plugins/midi_import/portsmf/allegrowr.cpp index f4a76f18a..3b266f84c 100644 --- a/plugins/midi_import/portsmf/allegrowr.cpp +++ b/plugins/midi_import/portsmf/allegrowr.cpp @@ -1,6 +1,6 @@ // allegrowr.cpp -- write sequence to an Allegro file (text) -#include "assert.h" +#include "debug.h" #include "stdlib.h" #include #include diff --git a/plugins/opl2/CMakeLists.txt b/plugins/opl2/CMakeLists.txt index 0b9bd32cd..981ec53a3 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 000000000..4362b4915 --- /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 9aac3a6fc..000000000 --- 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 8600d787d..000000000 --- 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 2b0e82b0c..db5180189 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 d2ca6e288..000000000 --- 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 a5b8256e4..fab030160 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 34fd186df..5f41b6454 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 6933d7479..9f47a0cfe 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 e2f940b94..e41bdc2c2 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/patman/patman.cpp b/plugins/patman/patman.cpp index a5a588b21..b2cdc9d1b 100644 --- a/plugins/patman/patman.cpp +++ b/plugins/patman/patman.cpp @@ -25,7 +25,6 @@ #include "patman.h" -#include #include #include #include @@ -39,6 +38,7 @@ #include "song.h" #include "string_pair_drag.h" #include "tooltip.h" +#include "FileDialog.h" #include "embed.cpp" @@ -508,11 +508,8 @@ PatmanView::~PatmanView() void PatmanView::openFile( void ) { - QFileDialog ofd( NULL, tr( "Open patch file" ) ); -#if QT_VERSION >= 0x040806 - ofd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif - ofd.setFileMode( QFileDialog::ExistingFiles ); + FileDialog ofd( NULL, tr( "Open patch file" ) ); + ofd.setFileMode( FileDialog::ExistingFiles ); QStringList types; types << tr( "Patch-Files (*.pat)" ); diff --git a/plugins/peak_controller_effect/artwork.png b/plugins/peak_controller_effect/artwork.png index 1c5d5defb..31296ca90 100644 Binary files a/plugins/peak_controller_effect/artwork.png and b/plugins/peak_controller_effect/artwork.png differ diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 2467e717c..368a9779b 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -27,9 +27,9 @@ #include #include #include -#include #include +#include "FileDialog.h" #include "sf2_player.h" #include "engine.h" #include "InstrumentTrack.h" @@ -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 ) { @@ -1044,11 +1054,8 @@ void sf2InstrumentView::showFileDialog() { sf2Instrument * k = castModel(); - QFileDialog ofd( NULL, tr( "Open SoundFont file" ) ); -#if QT_VERSION >= 0x040806 - ofd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif - ofd.setFileMode( QFileDialog::ExistingFiles ); + FileDialog ofd( NULL, tr( "Open SoundFont file" ) ); + ofd.setFileMode( FileDialog::ExistingFiles ); QStringList types; types << tr( "SoundFont2 Files (*.sf2)" ); diff --git a/plugins/sf2_player/sf2_player.h b/plugins/sf2_player/sf2_player.h index 903480605..691a2be83 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/sfxr/CMakeLists.txt b/plugins/sfxr/CMakeLists.txt new file mode 100644 index 000000000..2fe490d1e --- /dev/null +++ b/plugins/sfxr/CMakeLists.txt @@ -0,0 +1,3 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(sfxr sfxr.cpp sfxr.h MOCFILES sfxr.h EMBEDDED_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.png) diff --git a/plugins/sfxr/artwork.png b/plugins/sfxr/artwork.png new file mode 100644 index 000000000..15f313d45 Binary files /dev/null and b/plugins/sfxr/artwork.png differ diff --git a/plugins/sfxr/blip_active.png b/plugins/sfxr/blip_active.png new file mode 100644 index 000000000..f3113f772 Binary files /dev/null and b/plugins/sfxr/blip_active.png differ diff --git a/plugins/sfxr/blip_inactive.png b/plugins/sfxr/blip_inactive.png new file mode 100644 index 000000000..e8e5ca112 Binary files /dev/null and b/plugins/sfxr/blip_inactive.png differ diff --git a/plugins/sfxr/explosion_active.png b/plugins/sfxr/explosion_active.png new file mode 100644 index 000000000..b6af2a916 Binary files /dev/null and b/plugins/sfxr/explosion_active.png differ diff --git a/plugins/sfxr/explosion_inactive.png b/plugins/sfxr/explosion_inactive.png new file mode 100644 index 000000000..67c89f013 Binary files /dev/null and b/plugins/sfxr/explosion_inactive.png differ diff --git a/plugins/sfxr/hit_active.png b/plugins/sfxr/hit_active.png new file mode 100644 index 000000000..5bc6c9a14 Binary files /dev/null and b/plugins/sfxr/hit_active.png differ diff --git a/plugins/sfxr/hit_inactive.png b/plugins/sfxr/hit_inactive.png new file mode 100644 index 000000000..a16f7eca3 Binary files /dev/null and b/plugins/sfxr/hit_inactive.png differ diff --git a/plugins/sfxr/jump_active.png b/plugins/sfxr/jump_active.png new file mode 100644 index 000000000..6f1ff1ee5 Binary files /dev/null and b/plugins/sfxr/jump_active.png differ diff --git a/plugins/sfxr/jump_inactive.png b/plugins/sfxr/jump_inactive.png new file mode 100644 index 000000000..cc67812eb Binary files /dev/null and b/plugins/sfxr/jump_inactive.png differ diff --git a/plugins/sfxr/laser_active.png b/plugins/sfxr/laser_active.png new file mode 100644 index 000000000..04a5de94c Binary files /dev/null and b/plugins/sfxr/laser_active.png differ diff --git a/plugins/sfxr/laser_inactive.png b/plugins/sfxr/laser_inactive.png new file mode 100644 index 000000000..bf7eb18d1 Binary files /dev/null and b/plugins/sfxr/laser_inactive.png differ diff --git a/plugins/sfxr/logo.png b/plugins/sfxr/logo.png new file mode 100644 index 000000000..a39e4e865 Binary files /dev/null and b/plugins/sfxr/logo.png differ diff --git a/plugins/sfxr/mutate_active.png b/plugins/sfxr/mutate_active.png new file mode 100644 index 000000000..31cf797b1 Binary files /dev/null and b/plugins/sfxr/mutate_active.png differ diff --git a/plugins/sfxr/mutate_inactive.png b/plugins/sfxr/mutate_inactive.png new file mode 100644 index 000000000..31afa4c0e Binary files /dev/null and b/plugins/sfxr/mutate_inactive.png differ diff --git a/plugins/sfxr/pickup_active.png b/plugins/sfxr/pickup_active.png new file mode 100644 index 000000000..69c81b33c Binary files /dev/null and b/plugins/sfxr/pickup_active.png differ diff --git a/plugins/sfxr/pickup_inactive.png b/plugins/sfxr/pickup_inactive.png new file mode 100644 index 000000000..a4502ce56 Binary files /dev/null and b/plugins/sfxr/pickup_inactive.png differ diff --git a/plugins/sfxr/powerup_active.png b/plugins/sfxr/powerup_active.png new file mode 100644 index 000000000..6be7826cc Binary files /dev/null and b/plugins/sfxr/powerup_active.png differ diff --git a/plugins/sfxr/powerup_inactive.png b/plugins/sfxr/powerup_inactive.png new file mode 100644 index 000000000..c12fc18f9 Binary files /dev/null and b/plugins/sfxr/powerup_inactive.png differ diff --git a/plugins/sfxr/randomize_active.png b/plugins/sfxr/randomize_active.png new file mode 100644 index 000000000..e730c42fe Binary files /dev/null and b/plugins/sfxr/randomize_active.png differ diff --git a/plugins/sfxr/randomize_inactive.png b/plugins/sfxr/randomize_inactive.png new file mode 100644 index 000000000..147c75f70 Binary files /dev/null and b/plugins/sfxr/randomize_inactive.png differ diff --git a/plugins/sfxr/readme.txt b/plugins/sfxr/readme.txt new file mode 100644 index 000000000..27882c77f --- /dev/null +++ b/plugins/sfxr/readme.txt @@ -0,0 +1,170 @@ +This is a port of sfxr to LMMS, ported by Wong Cho Ching. + +NOTE: Do NOT remove the MIT license below to prevent legal problem. +Original Readme File: + +(http://www.drpetter.se/project_sfxr.html) + +----------------------------- +sfxr - sound effect generator +----------------------------- + by DrPetter, 2007-12-14 + developed for LD48#10 +----------------------------- + + +Basic usage: + +Start the application, then hit +some of the buttons on the left +side to generate random sounds +matching the button descriptions. + +Press "Export .WAV" to save the +current sound as a WAV audio file. +Click the buttons below to change +WAV format in terms of bits per +sample and sample rate. + +If you find a sound that is sort +of interesting but not quite what +you want, you can drag some sliders +around until it sounds better. + +The Randomize button generates +something completely random. + +Mutate slightly alters the current +parameters to automatically create +a variation of the sound. + + + +Advanced usage: + +Figure out what each slider does and +use them to adjust particular aspects +of the current sound... + +Press the right mouse button on a slider +to reset it to a value of zero. + +Press Space or Enter to play the current sound. + +The Save/Load sound buttons allow saving +and loading of program parameters to work +on a sound over several sessions. + +Volume setting is saved with the sound and +exported to WAV. If you increase it too much +there's a risk of clipping. + +Some parameters influence the sound during +playback (particularly when using a non-zero +repeat speed), and dragging these sliders +can cause some interesting effects. +To record this you will need to use an external +recording application, for instance Audacity. +Set the recording source in that application +to "Wave", "Stereo Mix", "Mixed Output" or similar. + +Using an external sound editor to capture and edit +sound can also be used to string several sounds +together for more complex results. + +Parameter description: +- The top four buttons select base waveform +- First four parameters control the volume envelope + Attack is the beginning of the sound, + longer attack means a smoother start. + Sustain is how long the volume is held constant + before fading out. + Increase Sustain Punch to cause a popping + effect with increased (and falling) volume + during the sustain phase. + Decay is the fade-out time. +- Next six are for controlling the sound pitch or + frequency. + Start frequency is pretty obvious. Has a large + impact on the overall sound. + Min frequency represents a cutoff that stops all + sound if it's passed during a downward slide. + Slide sets the speed at which the frequency should + be swept (up or down). + Delta slide is the "slide of slide", or rate of change + in the slide speed. + Vibrato depth/speed makes for an oscillating + frequency effect at various strengths and rates. +- Then we have two parameters for causing an abrupt + change in pitch after a ceratin delay. + Amount is pitch change (up or down) + and Speed indicates time to wait before changing + the pitch. +- Following those are two parameters specific to the + squarewave waveform. + The duty cycle of a square describes its shape + in terms of how large the positive vs negative + sections are. It can be swept up or down by + changing the second parameter. +- Repeat speed, when not zero, causes the frequency + and duty parameters to be reset at regular intervals + while the envelope and filter continue unhindered. + This can make for some interesting pulsating effects. +- Phaser offset overlays a delayed copy of the audio + stream on top of itself, resulting in a kind of tight + reverb or sci-fi effect. + This parameter can also be swept like many others. +- Finally, the bottom five sliders control two filters + which are applied after all other effects. + The first one is a resonant lowpass filter which has + a sweepable cutoff frequency. + The other is a highpass filter which can be used to + remove undesired low frequency hum in "light" sounds. + + +---------------------- + + +License +------- + +Basically, I don't care what you do with it, anything goes. + +To please all the troublesome folks who request a formal license, +I attach the "MIT license" as follows: + +-- + +Copyright (c) 2007 Tomas Pettersson + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + + + +---------------------- + +http://www.drpetter.se + + drpetter@gmail.com + +---------------------- + diff --git a/plugins/sfxr/sfxr.cpp b/plugins/sfxr/sfxr.cpp new file mode 100644 index 000000000..66f9b58a1 --- /dev/null +++ b/plugins/sfxr/sfxr.cpp @@ -0,0 +1,1063 @@ +/* + * sfxr.cpp - port of sfxr to LMMS + * Originally written by Tomas Pettersson. For the original license, + * please read readme.txt in this directory + * + * Copyright (c) 2014 Wong Cho Ching + * + * 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. + */ + +#include +#include + +#define rnd(n) (rand()%(n+1)) + +#define PI 3.14159265f + +float frnd(float range) +{ + return (float)rnd(10000)/10000*range; +} + + +#include + +#include "sfxr.h" +#include "engine.h" +#include "InstrumentTrack.h" +#include "knob.h" +#include "note_play_handle.h" +#include "pixmap_button.h" +#include "song_editor.h" +#include "templates.h" +#include "tooltip.h" +#include "song.h" + +#include "embed.cpp" + +extern "C" +{ + +Plugin::Descriptor PLUGIN_EXPORT sfxr_plugin_descriptor = +{ + STRINGIFY( PLUGIN_NAME ), + "sfxr", + QT_TRANSLATE_NOOP( "pluginBrowser", + "LMMS port of sfxr" ), + "Wong Cho Ching", + 0x0100, + Plugin::Instrument, + new PluginPixmapLoader( "logo" ), + NULL, + NULL +} ; + +} + + + + +SfxrSynth::SfxrSynth( const sfxrInstrument * s ): + s(s), + playing_sample( true ) +{ + resetSample( false ); +} + + + + +SfxrSynth::~SfxrSynth() +{ + +} + + + + +void SfxrSynth::resetSample( bool restart ) +{ + if(!restart) + { + phase=0; + } + fperiod=100.0/(s->m_startFreqModel.value()*s->m_startFreqModel.value()+0.001); + period=(int)fperiod; + fmaxperiod=100.0/(s->m_minFreqModel.value()*s->m_minFreqModel.value()+0.001); + fslide=1.0-pow((double)s->m_slideModel.value(), 3.0)*0.01; + fdslide=-pow((double)s->m_dSlideModel.value(), 3.0)*0.000001; + square_duty=0.5f-s->m_sqrDutyModel.value()*0.5f; + square_slide=-s->m_sqrSweepModel.value()*0.00005f; + if(s->m_changeAmtModel.value()>=0.0f) + arp_mod=1.0-pow((double)s->m_changeAmtModel.value(), 2.0)*0.9; + else + arp_mod=1.0+pow((double)s->m_changeAmtModel.value(), 2.0)*10.0; + arp_time=0; + arp_limit=(int)(pow(1.0f-s->m_changeSpeedModel.value(), 2.0f)*20000+32); + if(s->m_changeSpeedModel.value()==1.0f) + arp_limit=0; + if(!restart) + { + // reset filter + fltp=0.0f; + fltdp=0.0f; + fltw=pow(s->m_lpFilCutModel.value(), 3.0f)*0.1f; + fltw_d=1.0f+s->m_lpFilCutSweepModel.value()*0.0001f; + fltdmp=5.0f/(1.0f+pow(s->m_lpFilResoModel.value(), 2.0f)*20.0f)*(0.01f+fltw); + if(fltdmp>0.8f) fltdmp=0.8f; + fltphp=0.0f; + flthp=pow(s->m_hpFilCutModel.value(), 2.0f)*0.1f; + flthp_d=1.0+s->m_hpFilCutSweepModel.value()*0.0003f; + // reset vibrato + vib_phase=0.0f; + vib_speed=pow(s->m_vibSpeedModel.value(), 2.0f)*0.01f; + vib_amp=s->m_vibDepthModel.value()*0.5f; + // reset envelope + env_vol=0.0f; + env_stage=0; + env_time=0; + env_length[0]=(int)(s->m_attModel.value()*s->m_attModel.value()*100000.0f); + env_length[1]=(int)(s->m_holdModel.value()*s->m_holdModel.value()*100000.0f); + env_length[2]=(int)(s->m_decModel.value()*s->m_decModel.value()*100000.0f); + + fphase=pow(s->m_phaserOffsetModel.value(), 2.0f)*1020.0f; + if(s->m_phaserOffsetModel.value()<0.0f) fphase=-fphase; + fdphase=pow(s->m_phaserSweepModel.value(), 2.0f)*1.0f; + if(s->m_phaserSweepModel.value()<0.0f) fdphase=-fdphase; + iphase=abs((int)fphase); + ipp=0; + for(int i=0;i<1024;i++) + phaser_buffer[i]=0.0f; + + for(int i=0;i<32;i++) + noise_buffer[i]=frnd(2.0f)-1.0f; + + rep_time=0; + rep_limit=(int)(pow(1.0f-s->m_repeatSpeedModel.value(), 2.0f)*20000+32); + if(s->m_repeatSpeedModel.value()==0.0f) + rep_limit=0; + } +} + + + + +void SfxrSynth::update( sampleFrame * buffer, const fpp_t frameNum ) +{ + for(int i=0;i=rep_limit) + { + rep_limit=0; + resetSample(true); + } + + // frequency envelopes/arpeggios + arp_time++; + if(arp_limit!=0 && arp_time>=arp_limit) + { + arp_limit=0; + fperiod*=arp_mod; + } + fslide+=fdslide; + fperiod*=fslide; + if(fperiod>fmaxperiod) + { + fperiod=fmaxperiod; + if(s->m_minFreqModel.value()>0.0f) + playing_sample=false; + } + float rfperiod=fperiod; + if(vib_amp>0.0f) + { + vib_phase+=vib_speed; + rfperiod=fperiod*(1.0+sin(vib_phase)*vib_amp); + } + period=(int)rfperiod; + if(period<8) period=8; + square_duty+=square_slide; + if(square_duty<0.0f) square_duty=0.0f; + if(square_duty>0.5f) square_duty=0.5f; + // volume envelope + env_time++; + if(env_time>env_length[env_stage]) + { + env_time=0; + env_stage++; + if(env_stage==3) + playing_sample=false; + } + if(env_stage==0) + env_vol=(float)env_time/env_length[0]; + if(env_stage==1) + env_vol=1.0f+pow(1.0f-(float)env_time/env_length[1], 1.0f)*2.0f*s->m_susModel.value(); + if(env_stage==2) + env_vol=1.0f-(float)env_time/env_length[2]; + + // phaser step + fphase+=fdphase; + iphase=abs((int)fphase); + if(iphase>1023) iphase=1023; + + if(flthp_d!=0.0f) + { + flthp*=flthp_d; + if(flthp<0.00001f) flthp=0.00001f; + if(flthp>0.1f) flthp=0.1f; + } + + float ssample=0.0f; + for(int si=0;si<8;si++) // 8x supersampling + { + float sample=0.0f; + phase++; + if(phase>=period) + { +// phase=0; + phase%=period; + if(s->m_waveFormModel.value()==3) + for(int i=0;i<32;i++) + noise_buffer[i]=frnd(2.0f)-1.0f; + } + // base waveform + float fp=(float)phase/period; + switch(s->m_waveFormModel.value()) + { + case 0: // square + if(fp0.1f) fltw=0.1f; + if(s->m_lpFilCutModel.value()!=1.0f) + { + fltdp+=(sample-fltp)*fltw; + fltdp-=fltdp*fltdmp; + } + else + { + fltp=sample; + fltdp=0.0f; + } + fltp+=fltdp; + // hp filter + fltphp+=fltp-pp; + fltphp-=fltphp*flthp; + sample=fltphp; + // phaser + phaser_buffer[ipp&1023]=sample; + sample+=phaser_buffer[(ipp-iphase+1024)&1023]; + ipp=(ipp+1)&1023; + // final accumulation and envelope application + ssample+=sample*env_vol; + } + //ssample=ssample/8*master_vol; + + //ssample*=2.0f*sound_vol; + ssample*=0.025f; + + if(buffer!=NULL) + { + if(ssample>1.0f) ssample=1.0f; + if(ssample<-1.0f) ssample=-1.0f; + for( ch_cnt_t j=0; jframesLeftForCurrentPeriod(); + if ( _n->totalFramesPlayed() == 0 ) + { + _n->m_pluginData = new SfxrSynth( this ); + } + else if( static_cast(_n->m_pluginData)->isPlaying() == false ) + { + _n->noteOff(); + return; + } + + fpp_t pitchedFrameNum = (_n->frequency()/BaseFreq)*frameNum; + sampleFrame * pitchedBuffer = new sampleFrame[pitchedFrameNum]; + static_cast(_n->m_pluginData)->update( pitchedBuffer, pitchedFrameNum ); + for( fpp_t i=0; iprocessAudioBuffer( _working_buffer, frameNum, NULL ); +} + + + + +void sfxrInstrument::deleteNotePluginData( notePlayHandle * _n ) +{ + delete static_cast( _n->m_pluginData ); +} + + + + +PluginView * sfxrInstrument::instantiateView( QWidget * _parent ) +{ + return( new sfxrInstrumentView( this, _parent ) ); +} + + + + +void sfxrInstrument::resetModels() +{ + + m_attModel.reset(); + m_holdModel.reset(); + m_susModel.reset(); + m_decModel.reset(); + + m_startFreqModel.reset(); + m_minFreqModel.reset(); + m_slideModel.reset(); + m_dSlideModel.reset(); + m_vibDepthModel.reset(); + m_vibSpeedModel.reset(); + + m_changeAmtModel.reset(); + m_changeSpeedModel.reset(); + + m_sqrDutyModel.reset(); + m_sqrSweepModel.reset(); + + m_repeatSpeedModel.reset(); + + m_phaserOffsetModel.reset(); + m_phaserSweepModel.reset(); + + m_lpFilCutModel.reset(); + m_lpFilCutSweepModel.reset(); + m_lpFilResoModel.reset(); + m_hpFilCutModel.reset(); + m_hpFilCutSweepModel.reset(); + + m_waveFormModel.reset(); +} + + + + +class sfxrKnob : public knob +{ +public: + sfxrKnob( QWidget * _parent ) : + knob( knobStyled, _parent ) + { + setFixedSize( 20, 20 ); + setCenterPointX( 10.0 ); + setCenterPointY( 10.0 ); + setTotalAngle( 270.0 ); + setLineWidth( 1 ); + } +}; + + + + +#define createKnob(_knob, _x, _y, _name)\ + _knob = new sfxrKnob( this ); \ + _knob->setHintText( tr( _name ":" ), "" ); \ + _knob->move( _x, _y ); \ + toolTip::add( _knob, tr( _name ) ); + + + + +#define createButton(_button, _x, _y, _name, _resName)\ + _button = new pixmapButton( this, tr( "Sine wave" ) );\ + _button->move( _x, _y );\ + _button->setActiveGraphic( embed::getIconPixmap( _resName "_active" ) );\ + _button->setInactiveGraphic( embed::getIconPixmap( _resName "_inactive" ) );\ + toolTip::add( _button, tr( _name ) ); + + + + +#define createButtonLocalGraphic(_button, _x, _y, _name, _resName)\ + _button = new pixmapButton( this, tr( "Sine wave" ) );\ + _button->move( _x, _y );\ + _button->setActiveGraphic( PLUGIN_NAME::getIconPixmap( _resName "_active" ) );\ + _button->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( _resName "_inactive" ) );\ + toolTip::add( _button, tr( _name ) ); + + + + +sfxrInstrumentView::sfxrInstrumentView( Instrument * _instrument, + QWidget * _parent ) : + InstrumentView( _instrument, _parent ) +{ + srand(time(NULL)); + setAutoFillBackground( true ); + QPalette pal; + pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); + setPalette( pal ); + + createKnob(m_attKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*0, "Attack Time"); + createKnob(m_holdKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*1, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*0, "Sustain Time"); + createKnob(m_susKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*2, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*0, "Sustain Punch"); + createKnob(m_decKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*0, "Decay Time"); + + createKnob(m_startFreqKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Start Frequency"); + createKnob(m_minFreqKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*1, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Min Frequency"); + createKnob(m_slideKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*2, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Slide"); + createKnob(m_dSlideKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Delta Slide"); + createKnob(m_vibDepthKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*4, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Vibrato Depth"); + createKnob(m_vibSpeedKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*5, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*1, "Vibrato Speed"); + + createKnob(m_changeAmtKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Change Amount"); + createKnob(m_changeSpeedKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*1, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Change Speed"); + + createKnob(m_sqrDutyKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Squre Duty(Square wave only)"); + createKnob(m_sqrSweepKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*4, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Squre Sweep(Square wave only)"); + + createKnob(m_repeatSpeedKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*3, "Repeat Speed"); + + createKnob(m_phaserOffsetKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*2, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*3, "Phaser Offset"); + createKnob(m_phaserSweepKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*3, "Phaser Sweep"); + + createKnob(m_lpFilCutKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*0, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "LP Filter Cutoff"); + createKnob(m_lpFilCutSweepKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*1, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "LP Filter Cutoff Sweep"); + createKnob(m_lpFilResoKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*2, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "LP Filter Resonance"); + createKnob(m_hpFilCutKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "HP Filter Cutoff"); + createKnob(m_hpFilCutSweepKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*4, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*4, "HP Filter Cutoff Sweep"); + + createButton(m_sqrWaveBtn, KNOBS_BASE_X+WAVEFORM_BUTTON_WIDTH*0, WAVEFORM_BASE_Y, "Square Wave", "square_wave"); + createButton(m_sawWaveBtn, KNOBS_BASE_X+WAVEFORM_BUTTON_WIDTH*1, WAVEFORM_BASE_Y, "Saw Wave", "saw_wave"); + createButton(m_sinWaveBtn, KNOBS_BASE_X+WAVEFORM_BUTTON_WIDTH*2, WAVEFORM_BASE_Y, "Sine Wave", "sin_wave"); + createButton(m_noiseWaveBtn, KNOBS_BASE_X+WAVEFORM_BUTTON_WIDTH*3, WAVEFORM_BASE_Y, "Noise", "white_noise_wave"); + + m_waveBtnGroup = new automatableButtonGroup( this ); + m_waveBtnGroup->addButton(m_sqrWaveBtn); + m_waveBtnGroup->addButton(m_sawWaveBtn); + m_waveBtnGroup->addButton(m_sinWaveBtn); + m_waveBtnGroup->addButton(m_noiseWaveBtn); + + + createButtonLocalGraphic(m_pickupBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*0, GENERATOR_BASE_Y, "Generate pick up/coin sfx", "pickup"); + createButtonLocalGraphic(m_laserBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*1, GENERATOR_BASE_Y, "Generate laser/shoot sfx", "laser"); + createButtonLocalGraphic(m_explosionBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*2, GENERATOR_BASE_Y, "Generate explosion sfx", "explosion"); + createButtonLocalGraphic(m_powerupBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*3, GENERATOR_BASE_Y, "Generate power up sfx", "powerup"); + createButtonLocalGraphic(m_hitBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*4, GENERATOR_BASE_Y, "Generate hit/hurt sfx", "hit"); + createButtonLocalGraphic(m_jumpBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*5, GENERATOR_BASE_Y, "Generate jump sfx", "jump"); + createButtonLocalGraphic(m_blipBtn, GENERATOR_BASE_X+GENERATOR_BUTTON_WIDTH*6, GENERATOR_BASE_Y, "Generate blip/select sfx", "blip"); + connect( m_pickupBtn, SIGNAL ( clicked() ), this, SLOT ( genPickup() ) ); + connect( m_laserBtn, SIGNAL ( clicked() ), this, SLOT ( genLaser() ) ); + connect( m_explosionBtn, SIGNAL ( clicked() ), this, SLOT ( genExplosion() ) ); + connect( m_powerupBtn, SIGNAL ( clicked() ), this, SLOT ( genPowerup() ) ); + connect( m_hitBtn, SIGNAL ( clicked() ), this, SLOT ( genHit() ) ); + connect( m_jumpBtn, SIGNAL ( clicked() ), this, SLOT ( genJump() ) ); + connect( m_blipBtn, SIGNAL ( clicked() ), this, SLOT ( genBlip() ) ); + + + createButtonLocalGraphic(m_randomizeBtn, RAND_BUTTON_X, RAND_BUTTON_Y, "Generate random sfx", "randomize"); + createButtonLocalGraphic(m_mutateBtn, MUTA_BUTTON_X, MUTA_BUTTON_Y, "Mutate sfx", "mutate"); + connect( m_randomizeBtn, SIGNAL ( clicked() ), this, SLOT ( randomize() ) ); + connect( m_mutateBtn, SIGNAL ( clicked() ), this, SLOT ( mutate() ) ); + + +} + + + + +void sfxrInstrumentView::modelChanged() +{ + sfxrInstrument * s = castModel(); + + m_attKnob->setModel( &s->m_attModel ); + m_holdKnob->setModel( &s->m_holdModel ); + m_susKnob->setModel( &s->m_susModel ); + m_decKnob->setModel( &s->m_decModel ); + + m_startFreqKnob->setModel( &s->m_startFreqModel ); + m_minFreqKnob->setModel( &s->m_minFreqModel ); + m_slideKnob->setModel( &s->m_slideModel ); + m_dSlideKnob->setModel( &s->m_dSlideModel ); + m_vibDepthKnob->setModel( &s->m_vibDepthModel ); + m_vibSpeedKnob->setModel( &s->m_vibSpeedModel ); + + m_changeAmtKnob->setModel( &s->m_changeAmtModel ); + m_changeSpeedKnob->setModel( &s->m_changeSpeedModel ); + + m_sqrDutyKnob->setModel( &s->m_sqrDutyModel ); + m_sqrSweepKnob->setModel( &s->m_sqrSweepModel ); + + m_repeatSpeedKnob->setModel( &s->m_repeatSpeedModel ); + + m_phaserOffsetKnob->setModel( &s->m_phaserOffsetModel ); + m_phaserSweepKnob->setModel( &s->m_phaserSweepModel ); + + m_lpFilCutKnob->setModel( &s->m_lpFilCutModel ); + m_lpFilCutSweepKnob->setModel( &s->m_lpFilCutSweepModel ); + m_lpFilResoKnob->setModel( &s->m_lpFilResoModel ); + m_hpFilCutKnob->setModel( &s->m_hpFilCutModel ); + m_hpFilCutSweepKnob->setModel( &s->m_hpFilCutSweepModel ); + + m_waveBtnGroup->setModel( &s->m_waveFormModel ); +} + + + + +void sfxrInstrumentView::genPickup() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + s->m_startFreqModel.setValue( 0.4f+frnd(0.5f) ); + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( frnd(0.1f) ); + s->m_decModel.setValue( 0.1f+frnd(0.4f) ); + s->m_susModel.setValue( 0.3f+frnd(0.3f) ); + + if(rnd(1)) + { + s->m_changeSpeedModel.setValue( 0.5f+frnd(0.2f) ); + s->m_changeAmtModel.setValue( 0.2f+frnd(0.4f) ); + } +} + + + + +void sfxrInstrumentView::genLaser() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( rnd(2) ); + if(s->m_waveFormModel.value()==2 && rnd(1)) + s->m_waveFormModel.setValue( rnd(1) ); + + s->m_startFreqModel.setValue( 0.5f+frnd(0.5f) ); + s->m_minFreqModel.setValue( s->m_startFreqModel.value()-0.2f-frnd(0.6f) ); + + if(s->m_minFreqModel.value()<0.2f) + { + s->m_minFreqModel.setValue(0.2f); + } + + s->m_slideModel.setValue( -0.15f-frnd(0.2f) ); + + if(rnd(2)==0) + { + s->m_startFreqModel.setValue( 0.3f+frnd(0.6f) ); + s->m_minFreqModel.setValue( frnd(0.1f) ); + s->m_slideModel.setValue( -0.35f-frnd(0.3f) ); + } + + if(rnd(1)) + { + s->m_sqrDutyModel.setValue( frnd(0.5f) ); + s->m_sqrSweepModel.setValue( 0.2f ); + } + else + { + s->m_sqrDutyModel.setValue( 0.4f+frnd(0.5f) ); + s->m_sqrSweepModel.setValue( -frnd(0.7f) ); + } + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( 0.1f+frnd(0.2f) ); + s->m_decModel.setValue( frnd(0.4f) ); + + if(rnd(1)) + { + s->m_susModel.setValue( frnd(0.3f) ); + } + + if(rnd(2)==0) + { + s->m_phaserOffsetModel.setValue( frnd(0.2f) ); + s->m_phaserSweepModel.setValue( -frnd(0.2f) ); + } + + if(rnd(1)) + s->m_hpFilCutModel.setValue( frnd(0.3f) ); +} + + + + +void sfxrInstrumentView::genExplosion() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( 3 ); + + if(rnd(1)) + { + s->m_startFreqModel.setValue( 0.1f+frnd(0.4f) ); + s->m_slideModel.setValue( -0.1f+frnd(0.4f) ); + } + else + { + s->m_startFreqModel.setValue( 0.2f+frnd(0.7f) ); + s->m_slideModel.setValue( -0.2f-frnd(0.2f) ); + } + s->m_startFreqModel.setValue( s->m_startFreqModel.value()*s->m_startFreqModel.value() ); + + if(rnd(4)==0) + { + s->m_slideModel.setValue( 0.0f ); + } + + if(rnd(2)==0) + { + s->m_repeatSpeedModel.setValue( 0.3f+frnd(0.5f) ); + } + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( 0.1f+frnd(0.3f) ); + s->m_decModel.setValue( 0.5f ); + if(rnd(1)==0) + { + s->m_phaserOffsetModel.setValue( -0.3f+frnd(0.9f) ); + s->m_phaserSweepModel.setValue( -frnd(0.3f) ); + } + s->m_susModel.setValue( 0.2f+frnd(0.6f) ); + + if(rnd(1)) + { + s->m_vibDepthModel.setValue( frnd(0.7f) ); + s->m_vibSpeedModel.setValue( frnd(0.6f) ); + } + if(rnd(2)==0) + { + s->m_changeSpeedModel.setValue( 0.6f+frnd(0.3f) ); + s->m_changeAmtModel.setValue( 0.8f-frnd(1.6f) ); + } + +} + + + + +void sfxrInstrumentView::genPowerup() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + if(rnd(1)) + s->m_waveFormModel.setValue( 1 ); + else + s->m_sqrDutyModel.setValue( frnd(0.6f) ); + if(rnd(1)) + { + s->m_startFreqModel.setValue( 0.2f+frnd(0.3f) ); + s->m_slideModel.setValue( 0.1f+frnd(0.4f) ); + s->m_repeatSpeedModel.setValue( 0.4f+frnd(0.4f) ); + } + else + { + s->m_startFreqModel.setValue( 0.2f+frnd(0.3f) ); + s->m_slideModel.setValue( 0.05f+frnd(0.2f) ); + if(rnd(1)) + { + s->m_vibDepthModel.setValue( frnd(0.7f) ); + s->m_vibSpeedModel.setValue( frnd(0.6f) ); + } + } + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( frnd(0.4f) ); + s->m_decModel.setValue( 0.1f+frnd(0.4f) ); +} + + + + +void sfxrInstrumentView::genHit() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( rnd(2) ); + if(s->m_waveFormModel.value()==2) + { + s->m_waveFormModel.setValue( 3 ); + } + if(s->m_waveFormModel.value()==0) + { + s->m_sqrDutyModel.setValue( frnd(0.6f) ); + } + + s->m_startFreqModel.setValue( 0.2f+frnd(0.6f) ); + s->m_slideModel.setValue( -0.3f-frnd(0.4f) ); + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( frnd(0.1f) ); + s->m_decModel.setValue( 0.1f+frnd(0.2f) ); + if(rnd(1)) + { + s->m_hpFilCutModel.setValue( frnd(0.3f) ); + } +} + + + + +void sfxrInstrumentView::genJump() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( 0 ); + s->m_sqrDutyModel.setValue( frnd(0.6f) ); + + s->m_startFreqModel.setValue( 0.3f+frnd(0.3f) ); + s->m_slideModel.setValue( 0.1f+frnd(0.2f) ); + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( 0.1f+frnd(0.3f) ); + s->m_decModel.setValue( 0.1f+frnd(0.2f) ); + + if(rnd(1)) + { + s->m_hpFilCutModel.setValue( frnd(0.3f) ); + } + if(rnd(1)) + { + + s->m_lpFilCutModel.setValue( 1.0f-frnd(0.6f) ); + } + +} + + + + +void sfxrInstrumentView::genBlip() +{ + sfxrInstrument * s = castModel(); + s->resetModels(); + + s->m_waveFormModel.setValue( rnd(1) ); + if( s->m_waveFormModel.value()==0 ) + { + s->m_sqrDutyModel.setValue( frnd(0.6f) ); + } + + s->m_startFreqModel.setValue( 0.2f+frnd(0.4f) ); + + s->m_attModel.setValue( 0.0f ); + s->m_holdModel.setValue( 0.1f+frnd(0.1f) ); + s->m_decModel.setValue( frnd(0.2f) ); + s->m_hpFilCutModel.setValue( 0.1f ); +} + + + + +void sfxrInstrumentView::randomize() +{ + sfxrInstrument * s = castModel(); + + s->m_startFreqModel.setValue( pow(frnd(2.0f)-1.0f, 2.0f) ); + if(rnd(1)) + { + s->m_startFreqModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f)+0.5f ); + } + s->m_minFreqModel.setValue( 0.0f ); + s->m_slideModel.setValue( pow(frnd(2.0f)-1.0f, 5.0f) ); + if( s->m_startFreqModel.value()>0.7f && s->m_slideModel.value()>0.2f ) + { + s->m_slideModel.setValue( -s->m_slideModel.value() ); + } + if( s->m_startFreqModel.value()<0.2f && s->m_slideModel.value()<-0.05f ) + { + s->m_slideModel.setValue( -s->m_slideModel.value() ); + } + s->m_dSlideModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + + s->m_sqrDutyModel.setValue( frnd(2.0f)-1.0f ); + s->m_sqrSweepModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + + s->m_vibDepthModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + s->m_vibSpeedModel.setValue( frnd(2.0f)-1.0f ); + //s->m_vibDelayModel.setValue( frnd(2.0f)-1.0f ); + + s->m_attModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + s->m_holdModel.setValue( pow(frnd(2.0f)-1.0f, 2.0f) ); + s->m_decModel.setValue( frnd(2.0f)-1.0f ); + s->m_susModel.setValue( pow(frnd(0.8f), 2.0f) ); + if(s->m_attModel.value()+s->m_holdModel.value()+s->m_decModel.value()<0.2f) + { + s->m_holdModel.setValue( s->m_holdModel.value()+0.2f+frnd(0.3f) ); + s->m_decModel.setValue( s->m_decModel.value()+0.2f+frnd(0.3f) ); + } + + s->m_lpFilResoModel.setValue( frnd(2.0f)-1.0f ); + s->m_lpFilCutModel.setValue( 1.0f-pow(frnd(1.0f), 3.0f) ); + s->m_lpFilCutSweepModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + if(s->m_lpFilCutModel.value()<0.1f && s->m_lpFilCutSweepModel.value()<-0.05f) + { + s->m_lpFilCutSweepModel.setValue( -s->m_lpFilCutSweepModel.value() ); + } + s->m_hpFilCutModel.setValue( pow(frnd(1.0f), 5.0f) ); + s->m_hpFilCutSweepModel.setValue( pow(frnd(2.0f)-1.0f, 5.0f) ); + + s->m_phaserOffsetModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + s->m_phaserSweepModel.setValue( pow(frnd(2.0f)-1.0f, 3.0f) ); + + s->m_repeatSpeedModel.setValue( frnd(2.0f)-1.0f ); + + s->m_changeSpeedModel.setValue( frnd(2.0f)-1.0f ); + s->m_changeAmtModel.setValue( frnd(2.0f)-1.0f ); + +} + + + + +void sfxrInstrumentView::mutate() +{ + sfxrInstrument * s = castModel(); + + if(rnd(1)) s->m_startFreqModel.setValue( s->m_startFreqModel.value()+frnd(0.1f)-0.05f ); + // if(rnd(1)) s->m_minFreqModel.setValue( s->m_minFreqModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_slideModel.setValue( s->m_slideModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_dSlideModel.setValue( s->m_dSlideModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_sqrDutyModel.setValue( s->m_sqrDutyModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_sqrSweepModel.setValue( s->m_sqrSweepModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_vibDepthModel.setValue( s->m_vibDepthModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_vibSpeedModel.setValue( s->m_vibSpeedModel.value()+frnd(0.1f)-0.05f ); + // if(rnd(1)) s->m_vibDelayModel.setValue( s->m_vibDelayModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_attModel.setValue( s->m_attModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_holdModel.setValue( s->m_holdModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_decModel.setValue( s->m_decModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_susModel.setValue( s->m_susModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_lpFilResoModel.setValue( s->m_lpFilResoModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_lpFilCutModel.setValue( s->m_lpFilCutModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_lpFilCutSweepModel.setValue( s->m_lpFilCutSweepModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_hpFilCutModel.setValue( s->m_hpFilCutModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_hpFilCutSweepModel.setValue( s->m_hpFilCutSweepModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_phaserOffsetModel.setValue( s->m_phaserOffsetModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_phaserSweepModel.setValue( s->m_phaserSweepModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_repeatSpeedModel.setValue( s->m_repeatSpeedModel.value()+frnd(0.1f)-0.05f ); + + if(rnd(1)) s->m_changeSpeedModel.setValue( s->m_changeSpeedModel.value()+frnd(0.1f)-0.05f ); + if(rnd(1)) s->m_changeAmtModel.setValue( s->m_changeAmtModel.value()+frnd(0.1f)-0.05f ); + +} + + + + +extern "C" +{ + +// necessary for getting instance out of shared lib +Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data ) +{ + return( new sfxrInstrument( static_cast( _data ) ) ); +} + + +} + + + +#include "moc_sfxr.cxx" diff --git a/plugins/sfxr/sfxr.h b/plugins/sfxr/sfxr.h new file mode 100644 index 000000000..20250db70 --- /dev/null +++ b/plugins/sfxr/sfxr.h @@ -0,0 +1,300 @@ +/* + * sfxr.h - declaration of classes of the LMMS sfxr plugin + * Originally written by Tomas Pettersson. For the original license, + * please read readme.txt in this directory + * + * Copyright (c) 2014 Wong Cho Ching + * + * 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 _SFXR_H +#define _SFXR_H + +#include "Instrument.h" +#include "InstrumentView.h" +#include "knob.h" +#include "graph.h" +#include "pixmap_button.h" +#include "led_checkbox.h" + + +enum SfxrWaves +{ + SQR_WAVE, SAW_WAVE, SINE_WAVE, NOISE_WAVE, WAVES_NUM +}; + +const int WAVEFORM_BASE_X = 20; +const int WAVEFORM_BASE_Y = 14; +const int WAVEFORM_BUTTON_WIDTH = 16; + +const int GENERATOR_BASE_X = 110; +const int GENERATOR_BASE_Y = 24; +const int GENERATOR_BUTTON_WIDTH = 16; + +const int RAND_BUTTON_X = 160; +const int RAND_BUTTON_Y = 4; + +const int MUTA_BUTTON_X = 205; +const int MUTA_BUTTON_Y = 4; + +const int KNOBS_BASE_X = 20; +const int KNOBS_BASE_Y = 50; +const int KNOB_BLOCK_SIZE_X = 40; +const int KNOB_BLOCK_SIZE_Y = 40; + + + + +class sfxrInstrument; + + + +class SfxrSynth +{ +public: + SfxrSynth( const sfxrInstrument * s ); + virtual ~SfxrSynth(); + + void resetSample( bool restart ); + void update( sampleFrame * buffer, const fpp_t frameNum ); + + bool isPlaying() const; + +private: + const sfxrInstrument * s; + bool playing_sample; + int phase; + double fperiod; + double fmaxperiod; + double fslide; + double fdslide; + int period; + float square_duty; + float square_slide; + int env_stage; + int env_time; + int env_length[3]; + float env_vol; + float fphase; + float fdphase; + int iphase; + float phaser_buffer[1024]; + int ipp; + float noise_buffer[32]; + float fltp; + float fltdp; + float fltw; + float fltw_d; + float fltdmp; + float fltphp; + float flthp; + float flthp_d; + float vib_phase; + float vib_speed; + float vib_amp; + int rep_time; + int rep_limit; + int arp_time; + int arp_limit; + double arp_mod; + +} ; + + + +/** + * @brief A class that simplify the constructor of FloatModel, with value [0,1] + */ +class SfxrZeroToOneFloatModel : public FloatModel +{ +public: + SfxrZeroToOneFloatModel(float val, Model * parent): + FloatModel( val, 0.0, 1.0, 0.001, parent) + { + } + /* purpose: prevent the initial value of the model from being changed */ + virtual void loadSettings( const QDomElement& element, const QString& name = QString( "value" ) ) + { + float oldInitValue = initValue(); + FloatModel::loadSettings(element, name); + float oldValue = value(); + setInitValue(oldInitValue); + setValue(oldValue); + } +}; + +/** + * @brief A class that simplify the constructor of FloatModel, with value [-1,1] + */ +class SfxrNegPosOneFloatModel : public FloatModel +{ +public: + SfxrNegPosOneFloatModel(float val, Model * parent): + FloatModel( val, -1.0, 1.0, 0.001, parent) + { + } + /* purpose: prevent the initial value of the model from being changed */ + virtual void loadSettings( const QDomElement& element, const QString& name = QString( "value" ) ) + { + float oldInitValue = initValue(); + FloatModel::loadSettings(element, name); + float oldValue = value(); + setInitValue(oldInitValue); + setValue(oldValue); + } +}; + +class sfxrInstrument : public Instrument +{ + Q_OBJECT +public: + sfxrInstrument(InstrumentTrack * _instrument_track ); + virtual ~sfxrInstrument(); + + virtual void playNote( notePlayHandle * _n, sampleFrame * _working_buffer ); + virtual void deleteNotePluginData( notePlayHandle * _n ); + + virtual void saveSettings( QDomDocument & _doc, + QDomElement & _parent ); + virtual void loadSettings( const QDomElement & _this ); + + virtual QString nodeName() const; + + virtual PluginView * instantiateView( QWidget * _parent ); + + void resetModels(); + + +private: + SfxrZeroToOneFloatModel m_attModel; + SfxrZeroToOneFloatModel m_holdModel; + SfxrZeroToOneFloatModel m_susModel; + SfxrZeroToOneFloatModel m_decModel; + + SfxrZeroToOneFloatModel m_startFreqModel; + SfxrZeroToOneFloatModel m_minFreqModel; + SfxrNegPosOneFloatModel m_slideModel; + SfxrNegPosOneFloatModel m_dSlideModel; + SfxrZeroToOneFloatModel m_vibDepthModel; + SfxrZeroToOneFloatModel m_vibSpeedModel; + + SfxrNegPosOneFloatModel m_changeAmtModel; + SfxrZeroToOneFloatModel m_changeSpeedModel; + + SfxrZeroToOneFloatModel m_sqrDutyModel; + SfxrNegPosOneFloatModel m_sqrSweepModel; + + SfxrZeroToOneFloatModel m_repeatSpeedModel; + + SfxrNegPosOneFloatModel m_phaserOffsetModel; + SfxrNegPosOneFloatModel m_phaserSweepModel; + + SfxrZeroToOneFloatModel m_lpFilCutModel; + SfxrNegPosOneFloatModel m_lpFilCutSweepModel; + SfxrZeroToOneFloatModel m_lpFilResoModel; + SfxrZeroToOneFloatModel m_hpFilCutModel; + SfxrNegPosOneFloatModel m_hpFilCutSweepModel; + + IntModel m_waveFormModel; + + friend class sfxrInstrumentView; + friend class SfxrSynth; +}; + + + +class sfxrInstrumentView : public InstrumentView +{ + Q_OBJECT +public: + sfxrInstrumentView( Instrument * _instrument, + QWidget * _parent ); + + virtual ~sfxrInstrumentView() {}; + +protected slots: + void genPickup(); + void genLaser(); + void genExplosion(); + void genPowerup(); + void genHit(); + void genJump(); + void genBlip(); + void randomize(); + void mutate(); + +private: + virtual void modelChanged(); + + knob * m_attKnob; //Attack Time + knob * m_holdKnob; //Sustain Time + knob * m_susKnob; //Sustain Punch + knob * m_decKnob; //Decay Time + + knob * m_startFreqKnob; //Start Frequency + knob * m_minFreqKnob; //Min Frequency + knob * m_slideKnob; //Slide + knob * m_dSlideKnob; //Delta Slide + knob * m_vibDepthKnob; //Vibrato Depth + knob * m_vibSpeedKnob; //Vibrato Speed + + knob * m_changeAmtKnob; //Change Amount + knob * m_changeSpeedKnob; //Change Speed + + knob * m_sqrDutyKnob; //Squre Duty + knob * m_sqrSweepKnob; //Squre Sweep + + knob * m_repeatSpeedKnob; //Repeat Speed + + knob * m_phaserOffsetKnob; //Phaser Offset + knob * m_phaserSweepKnob; //Phaser Sweep + + knob * m_lpFilCutKnob; //LP Filter Cutoff + knob * m_lpFilCutSweepKnob; //LP Filter Cutoff Sweep + knob * m_lpFilResoKnob; //LP Filter Resonance + knob * m_hpFilCutKnob; //HP Filter Cutoff + knob * m_hpFilCutSweepKnob; //HP Filter Cutoff Sweep + + automatableButtonGroup * m_waveBtnGroup; + pixmapButton * m_sqrWaveBtn; //NOTE: This button has Squre Duty + //and Squre Speed configurable + pixmapButton * m_sawWaveBtn; + pixmapButton * m_sinWaveBtn; + pixmapButton * m_noiseWaveBtn; + + + pixmapButton * m_pickupBtn; + pixmapButton * m_laserBtn; + pixmapButton * m_explosionBtn; + pixmapButton * m_powerupBtn; + pixmapButton * m_hitBtn; + pixmapButton * m_jumpBtn; + pixmapButton * m_blipBtn; + + pixmapButton * m_randomizeBtn; + pixmapButton * m_mutateBtn; + + static QPixmap * s_artwork; +}; + + + +#endif diff --git a/plugins/triple_oscillator/TripleOscillator.cpp b/plugins/triple_oscillator/TripleOscillator.cpp index ae8510bab..20a017989 100644 --- a/plugins/triple_oscillator/TripleOscillator.cpp +++ b/plugins/triple_oscillator/TripleOscillator.cpp @@ -138,10 +138,9 @@ OscillatorObject::~OscillatorObject() void OscillatorObject::oscUserDefWaveDblClick() { - QString af = m_sampleBuffer->openAudioFile(); + QString af = m_sampleBuffer->openAndSetAudioFile(); if( af != "" ) { - m_sampleBuffer->setAudioFile( af ); // TODO: //toolTip::add( m_usrWaveBtn, m_sampleBuffer->audioFile() ); } diff --git a/plugins/triple_oscillator/artwork.png b/plugins/triple_oscillator/artwork.png index 7c61a87ec..b4940ae5e 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 6dfea9f69..f47efe689 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -25,7 +25,6 @@ #include "vestige.h" #include -#include #include #include #include @@ -43,6 +42,7 @@ #include "string_pair_drag.h" #include "text_float.h" #include "tooltip.h" +#include "FileDialog.h" #include "embed.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(); @@ -613,10 +612,7 @@ void VestigeInstrumentView::modelChanged() void VestigeInstrumentView::openPlugin() { - QFileDialog ofd( NULL, tr( "Open VST-plugin" ) ); -#if QT_VERSION >= 0x040806 - ofd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif + FileDialog ofd( NULL, tr( "Open VST-plugin" ) ); QString dir; if( m_vi->m_pluginDLL != "" ) @@ -629,7 +625,7 @@ void VestigeInstrumentView::openPlugin() } // change dir to position of previously opened file ofd.setDirectory( dir ); - ofd.setFileMode( QFileDialog::ExistingFiles ); + ofd.setFileMode( FileDialog::ExistingFiles ); // set filters QStringList types; @@ -782,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 600e87e22..b3e670305 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/vibed/vibed.cpp b/plugins/vibed/vibed.cpp index 7464e1daa..7872db7ca 100644 --- a/plugins/vibed/vibed.cpp +++ b/plugins/vibed/vibed.cpp @@ -728,9 +728,9 @@ void vibedView::noiseWaveClicked() void vibedView::usrWaveClicked() { - // TODO: load file - //m_graph->model()->setWaveToUser(); - //engine::getSongEditor()->setModified(); + QString fileName = m_graph->model()->setWaveToUser(); + toolTip::add( m_usrWaveBtn, fileName ); + engine::getSong()->setModified(); } diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 9100de316..9d1b278c3 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/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 8e331829b..5ed6164a4 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -24,7 +24,6 @@ #include "VstPlugin.h" -#include #include #include #include @@ -49,6 +48,7 @@ #include "MainWindow.h" #include "song.h" #include "templates.h" +#include "FileDialog.h" #include @@ -510,12 +510,9 @@ bool VstPlugin::processMessage( const message & _m ) void VstPlugin::openPreset( ) { - QFileDialog ofd( NULL, tr( "Open Preset" ), "", + FileDialog ofd( NULL, tr( "Open Preset" ), "", tr( "Vst Plugin Preset (*.fxp *.fxb)" ) ); -#if QT_VERSION >= 0x040806 - ofd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif - ofd.setFileMode( QFileDialog::ExistingFiles ); + ofd.setFileMode( FileDialog::ExistingFiles ); if( ofd.exec () == QDialog::Accepted && !ofd.selectedFiles().isEmpty() ) { @@ -571,19 +568,16 @@ void VstPlugin::savePreset( ) QString presName = currentProgramName().isEmpty() ? tr(": default") : currentProgramName(); presName.replace(tr("\""), tr("'")); // QFileDialog unable to handle double quotes properly - QFileDialog sfd( NULL, tr( "Save Preset" ), presName.section(": ", 1, 1) + tr(".fxp"), + FileDialog sfd( NULL, tr( "Save Preset" ), presName.section(": ", 1, 1) + tr(".fxp"), tr( "Vst Plugin Preset (*.fxp *.fxb)" ) ); -#if QT_VERSION >= 0x040806 - sfd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif if( p_name != "" ) // remember last directory { sfd.setDirectory( QFileInfo( p_name ).absolutePath() ); } - sfd.setAcceptMode( QFileDialog::AcceptSave ); - sfd.setFileMode( QFileDialog::AnyFile ); + sfd.setAcceptMode( FileDialog::AcceptSave ); + sfd.setFileMode( FileDialog::AnyFile ); if( sfd.exec () == QDialog::Accepted && !sfd.selectedFiles().isEmpty() && sfd.selectedFiles()[0] != "" ) { diff --git a/plugins/zynaddsubfx/LocalZynAddSubFx.cpp b/plugins/zynaddsubfx/LocalZynAddSubFx.cpp index 24e4ff182..6705bb33d 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 9d6d66345..3aeab8ba5 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 29300bf75..5e25de9fa 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 ad2dde50a..0984bfecf 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 f37ba857b..8ea46a124 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 7d158bdaa..2ef0b5705 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 9bfa6b47d..e3fb70d8c 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 6dfde4679..c11e68a7c 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 a9a3b5147..56791ade4 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 4babc3c50..1ce04941c 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/Controller.cpp b/src/core/Controller.cpp index 41bff4dcc..d1260fd35 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -3,6 +3,7 @@ * remote-control of AutomatableModels * * Copyright (c) 2008 Paul Giblock + * Copyright (c) 2014 Lukas W * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -53,8 +54,30 @@ Controller::Controller( ControllerTypes _type, Model * _parent, if( _type != DummyController && _type != MidiController ) { s_controllers.append( this ); - m_name = QString( tr( "Controller %1" ) ) - .arg( s_controllers.size() ); + // Determine which name to use + for ( uint i=s_controllers.size(); ; i++ ) + { + QString new_name = QString( tr( "Controller %1" ) ) + .arg( i ); + + // Check if name is already in use + bool name_used = false; + QVector::const_iterator it; + for ( it = s_controllers.constBegin(); + it != s_controllers.constEnd(); ++it ) + { + if ( (*it)->name() == new_name ) + { + name_used = true; + break; + } + } + if ( ! name_used ) + { + m_name = new_name; + break; + } + } } } diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index f6ef44715..985fd3152 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -33,111 +33,111 @@ -ChordCreator::ChordTable::Init ChordCreator::ChordTable::s_initTable[] = +InstrumentFunctionNoteStacking::ChordTable::Init InstrumentFunctionNoteStacking::ChordTable::s_initTable[] = { - { QT_TRANSLATE_NOOP( "ChordCreator", "octave" ), { 0, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Major" ), { 0, 4, 7, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Majb5" ), { 0, 4, 6, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "minor" ), { 0, 3, 7, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "minb5" ), { 0, 3, 6, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "sus2" ), { 0, 2, 7, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "sus4" ), { 0, 5, 7, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "aug" ), { 0, 4, 8, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "augsus4" ), { 0, 5, 8, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "tri" ), { 0, 3, 6, 9, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "octave" ), { 0, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Major" ), { 0, 4, 7, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Majb5" ), { 0, 4, 6, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "minor" ), { 0, 3, 7, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "minb5" ), { 0, 3, 6, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "sus2" ), { 0, 2, 7, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "sus4" ), { 0, 5, 7, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "aug" ), { 0, 4, 8, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "augsus4" ), { 0, 5, 8, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "tri" ), { 0, 3, 6, 9, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "6" ), { 0, 4, 7, 9, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "6sus4" ), { 0, 5, 7, 9, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "6add9" ), { 0, 4, 7, 9, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m6" ), { 0, 3, 7, 9, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m6add9" ), { 0, 3, 7, 9, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "6" ), { 0, 4, 7, 9, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "6sus4" ), { 0, 5, 7, 9, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "6add9" ), { 0, 4, 7, 9, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m6" ), { 0, 3, 7, 9, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m6add9" ), { 0, 3, 7, 9, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7" ), { 0, 4, 7, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7sus4" ), { 0, 5, 7, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7#5" ), { 0, 4, 8, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7b5" ), { 0, 4, 6, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7#9" ), { 0, 4, 7, 10, 15, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7b9" ), { 0, 4, 7, 10, 13, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7#5#9" ), { 0, 4, 8, 10, 15, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7#5b9" ), { 0, 4, 8, 10, 13, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7b5b9" ), { 0, 4, 6, 10, 13, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7add11" ), { 0, 4, 7, 10, 17, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7add13" ), { 0, 4, 7, 10, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "7#11" ), { 0, 4, 7, 10, 18, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj7" ), { 0, 4, 7, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj7b5" ), { 0, 4, 6, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj7#5" ), { 0, 4, 8, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj7#11" ), { 0, 4, 7, 11, 18, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj7add13" ), { 0, 4, 7, 11, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m7" ), { 0, 3, 7, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m7b5" ), { 0, 3, 6, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m7b9" ), { 0, 3, 7, 10, 13, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m7add11" ), { 0, 3, 7, 10, 17, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m7add13" ), { 0, 3, 7, 10, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m-Maj7" ), { 0, 3, 7, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m-Maj7add11" ), { 0, 3, 7, 11, 17, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m-Maj7add13" ), { 0, 3, 7, 11, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7" ), { 0, 4, 7, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7sus4" ), { 0, 5, 7, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7#5" ), { 0, 4, 8, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7b5" ), { 0, 4, 6, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7#9" ), { 0, 4, 7, 10, 15, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7b9" ), { 0, 4, 7, 10, 13, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7#5#9" ), { 0, 4, 8, 10, 15, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7#5b9" ), { 0, 4, 8, 10, 13, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7b5b9" ), { 0, 4, 6, 10, 13, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7add11" ), { 0, 4, 7, 10, 17, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7add13" ), { 0, 4, 7, 10, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "7#11" ), { 0, 4, 7, 10, 18, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj7" ), { 0, 4, 7, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj7b5" ), { 0, 4, 6, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj7#5" ), { 0, 4, 8, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj7#11" ), { 0, 4, 7, 11, 18, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj7add13" ), { 0, 4, 7, 11, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m7" ), { 0, 3, 7, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m7b5" ), { 0, 3, 6, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m7b9" ), { 0, 3, 7, 10, 13, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m7add11" ), { 0, 3, 7, 10, 17, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m7add13" ), { 0, 3, 7, 10, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m-Maj7" ), { 0, 3, 7, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m-Maj7add11" ), { 0, 3, 7, 11, 17, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m-Maj7add13" ), { 0, 3, 7, 11, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "9" ), { 0, 4, 7, 10, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "9sus4" ), { 0, 5, 7, 10, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "add9" ), { 0, 4, 7, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "9#5" ), { 0, 4, 8, 10, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "9b5" ), { 0, 4, 6, 10, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "9#11" ), { 0, 4, 7, 10, 14, 18, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "9b13" ), { 0, 4, 7, 10, 14, 20, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj9" ), { 0, 4, 7, 11, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj9sus4" ), { 0, 5, 7, 11, 15, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj9#5" ), { 0, 4, 8, 11, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj9#11" ), { 0, 4, 7, 11, 14, 18, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m9" ), { 0, 3, 7, 10, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "madd9" ), { 0, 3, 7, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m9b5" ), { 0, 3, 6, 10, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m9-Maj7" ), { 0, 3, 7, 11, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "9" ), { 0, 4, 7, 10, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "9sus4" ), { 0, 5, 7, 10, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "add9" ), { 0, 4, 7, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "9#5" ), { 0, 4, 8, 10, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "9b5" ), { 0, 4, 6, 10, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "9#11" ), { 0, 4, 7, 10, 14, 18, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "9b13" ), { 0, 4, 7, 10, 14, 20, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj9" ), { 0, 4, 7, 11, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj9sus4" ), { 0, 5, 7, 11, 15, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj9#5" ), { 0, 4, 8, 11, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj9#11" ), { 0, 4, 7, 11, 14, 18, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m9" ), { 0, 3, 7, 10, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "madd9" ), { 0, 3, 7, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m9b5" ), { 0, 3, 6, 10, 14, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m9-Maj7" ), { 0, 3, 7, 11, 14, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "11" ), { 0, 4, 7, 10, 14, 17, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "11b9" ), { 0, 4, 7, 10, 13, 17, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj11" ), { 0, 4, 7, 11, 14, 17, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m11" ), { 0, 3, 7, 10, 14, 17, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m-Maj11" ), { 0, 3, 7, 11, 14, 17, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "11" ), { 0, 4, 7, 10, 14, 17, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "11b9" ), { 0, 4, 7, 10, 13, 17, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj11" ), { 0, 4, 7, 11, 14, 17, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m11" ), { 0, 3, 7, 10, 14, 17, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m-Maj11" ), { 0, 3, 7, 11, 14, 17, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "13" ), { 0, 4, 7, 10, 14, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "13#9" ), { 0, 4, 7, 10, 15, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "13b9" ), { 0, 4, 7, 10, 13, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "13b5b9" ), { 0, 4, 6, 10, 13, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Maj13" ), { 0, 4, 7, 11, 14, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m13" ), { 0, 3, 7, 10, 14, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "m-Maj13" ), { 0, 3, 7, 11, 14, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "13" ), { 0, 4, 7, 10, 14, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "13#9" ), { 0, 4, 7, 10, 15, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "13b9" ), { 0, 4, 7, 10, 13, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "13b5b9" ), { 0, 4, 6, 10, 13, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Maj13" ), { 0, 4, 7, 11, 14, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m13" ), { 0, 3, 7, 10, 14, 21, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "m-Maj13" ), { 0, 3, 7, 11, 14, 21, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Major" ), { 0, 2, 4, 5, 7, 9, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Harmonic minor" ), { 0, 2, 3, 5, 7, 8, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Melodic minor" ), { 0, 2, 3, 5, 7, 9, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Whole tone" ), { 0, 2, 4, 6, 8, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Diminished" ), { 0, 2, 3, 5, 6, 8, 9, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Major pentatonic" ), { 0, 2, 4, 7, 9, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Minor pentatonic" ), { 0, 3, 5, 7, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Jap in sen" ), { 0, 1, 5, 7, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Major bebop" ), { 0, 2, 4, 5, 7, 8, 9, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Dominant bebop" ), { 0, 2, 4, 5, 7, 9, 10, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Blues" ), { 0, 3, 5, 6, 7, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Arabic" ), { 0, 1, 4, 5, 7, 8, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Enigmatic" ), { 0, 1, 4, 6, 8, 10, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Neopolitan" ), { 0, 1, 3, 5, 7, 9, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Neopolitan minor" ), { 0, 1, 3, 5, 7, 8, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Hungarian minor" ), { 0, 2, 3, 6, 7, 8, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Dorian" ), { 0, 2, 3, 5, 7, 9, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Phrygolydian" ), { 0, 1, 3, 5, 7, 8, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Lydian" ), { 0, 2, 4, 6, 7, 9, 11, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Mixolydian" ), { 0, 2, 4, 5, 7, 9, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Aeolian" ), { 0, 2, 3, 5, 7, 8, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Locrian" ), { 0, 1, 3, 5, 6, 8, 10, -1 } }, - { QT_TRANSLATE_NOOP( "ChordCreator", "Minor" ), { 0, 2, 3, 5, 7, 8, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Major" ), { 0, 2, 4, 5, 7, 9, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Harmonic minor" ), { 0, 2, 3, 5, 7, 8, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Melodic minor" ), { 0, 2, 3, 5, 7, 9, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Whole tone" ), { 0, 2, 4, 6, 8, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Diminished" ), { 0, 2, 3, 5, 6, 8, 9, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Major pentatonic" ), { 0, 2, 4, 7, 9, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Minor pentatonic" ), { 0, 3, 5, 7, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Jap in sen" ), { 0, 1, 5, 7, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Major bebop" ), { 0, 2, 4, 5, 7, 8, 9, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Dominant bebop" ), { 0, 2, 4, 5, 7, 9, 10, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Blues" ), { 0, 3, 5, 6, 7, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Arabic" ), { 0, 1, 4, 5, 7, 8, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Enigmatic" ), { 0, 1, 4, 6, 8, 10, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Neopolitan" ), { 0, 1, 3, 5, 7, 9, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Neopolitan minor" ), { 0, 1, 3, 5, 7, 8, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Hungarian minor" ), { 0, 2, 3, 6, 7, 8, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Dorian" ), { 0, 2, 3, 5, 7, 9, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Phrygolydian" ), { 0, 1, 3, 5, 7, 8, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Lydian" ), { 0, 2, 4, 6, 7, 9, 11, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Mixolydian" ), { 0, 2, 4, 5, 7, 9, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Aeolian" ), { 0, 2, 3, 5, 7, 8, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Locrian" ), { 0, 1, 3, 5, 6, 8, 10, -1 } }, + { QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Minor" ), { 0, 2, 3, 5, 7, 8, 10, -1 } }, } ; -ChordCreator::Chord::Chord( const char * n, const ChordSemiTones & semi_tones ) : - m_name( ChordCreator::tr( n ) ) +InstrumentFunctionNoteStacking::Chord::Chord( const char * n, const ChordSemiTones & semi_tones ) : + m_name( InstrumentFunctionNoteStacking::tr( n ) ) { for( m_size = 0; m_size < MAX_CHORD_POLYPHONY; m_size++ ) { @@ -153,7 +153,7 @@ ChordCreator::Chord::Chord( const char * n, const ChordSemiTones & semi_tones ) -bool ChordCreator::Chord::hasSemiTone( int8_t semi_tone ) const +bool InstrumentFunctionNoteStacking::Chord::hasSemiTone( int8_t semi_tone ) const { for( int i = 0; i < size(); ++i ) { @@ -168,7 +168,7 @@ bool ChordCreator::Chord::hasSemiTone( int8_t semi_tone ) const -ChordCreator::ChordTable::ChordTable() : +InstrumentFunctionNoteStacking::ChordTable::ChordTable() : QVector() { for( int i = 0; @@ -182,7 +182,7 @@ ChordCreator::ChordTable::ChordTable() : -const ChordCreator::Chord & ChordCreator::ChordTable::getByName( const QString & name, bool is_scale ) const +const InstrumentFunctionNoteStacking::Chord & InstrumentFunctionNoteStacking::ChordTable::getByName( const QString & name, bool is_scale ) const { for( int i = 0; i < size(); i++ ) { @@ -197,7 +197,7 @@ const ChordCreator::Chord & ChordCreator::ChordTable::getByName( const QString & -ChordCreator::ChordCreator( Model * _parent ) : +InstrumentFunctionNoteStacking::InstrumentFunctionNoteStacking( Model * _parent ) : Model( _parent, tr( "Chords" ) ), m_chordsEnabledModel( false, this ), m_chordsModel( this, tr( "Chord type" ) ), @@ -213,14 +213,14 @@ ChordCreator::ChordCreator( Model * _parent ) : -ChordCreator::~ChordCreator() +InstrumentFunctionNoteStacking::~InstrumentFunctionNoteStacking() { } -void ChordCreator::processNote( notePlayHandle * _n ) +void InstrumentFunctionNoteStacking::processNote( notePlayHandle * _n ) { const int base_note_key = _n->key(); const ChordTable & chord_table = ChordTable::getInstance(); @@ -229,9 +229,7 @@ void ChordCreator::processNote( notePlayHandle * _n ) // at the same time we only add sub-notes if nothing of the note was // played yet, because otherwise we would add chord-subnotes every // time an audio-buffer is rendered... - if( ( ( _n->isTopNote() && - _n->instrumentTrack()->isArpeggiatorEnabled() == false ) || - _n->isPartOfArpeggio() ) && + if( ( ( _n->isTopNote() && _n->instrumentTrack()->isArpeggioEnabled() == false ) || _n->isPartOfArpeggio() ) && _n->totalFramesPlayed() == 0 && m_chordsEnabledModel.value() == true ) { @@ -282,7 +280,7 @@ void ChordCreator::processNote( notePlayHandle * _n ) -void ChordCreator::saveSettings( QDomDocument & _doc, QDomElement & _this ) +void InstrumentFunctionNoteStacking::saveSettings( QDomDocument & _doc, QDomElement & _this ) { m_chordsEnabledModel.saveSettings( _doc, _this, "chord-enabled" ); m_chordsModel.saveSettings( _doc, _this, "chord" ); @@ -292,7 +290,7 @@ void ChordCreator::saveSettings( QDomDocument & _doc, QDomElement & _this ) -void ChordCreator::loadSettings( const QDomElement & _this ) +void InstrumentFunctionNoteStacking::loadSettings( const QDomElement & _this ) { m_chordsEnabledModel.loadSettings( _this, "chord-enabled" ); m_chordsModel.loadSettings( _this, "chord" ); @@ -305,7 +303,7 @@ void ChordCreator::loadSettings( const QDomElement & _this ) -Arpeggiator::Arpeggiator( Model * _parent ) : +InstrumentFunctionArpeggio::InstrumentFunctionArpeggio( Model * _parent ) : Model( _parent, tr( "Arpeggio" ) ), m_arpEnabledModel( false ), m_arpModel( this, tr( "Arpeggio type" ) ), @@ -317,7 +315,7 @@ Arpeggiator::Arpeggiator( Model * _parent ) : m_arpDirectionModel( this, tr( "Arpeggio direction" ) ), m_arpModeModel( this, tr( "Arpeggio mode" ) ) { - const ChordCreator::ChordTable & chord_table = ChordCreator::ChordTable::getInstance(); + const InstrumentFunctionNoteStacking::ChordTable & chord_table = InstrumentFunctionNoteStacking::ChordTable::getInstance(); for( int i = 0; i < chord_table.size(); ++i ) { m_arpModel.addItem( chord_table[i].getName() ); @@ -339,14 +337,14 @@ Arpeggiator::Arpeggiator( Model * _parent ) : -Arpeggiator::~Arpeggiator() +InstrumentFunctionArpeggio::~InstrumentFunctionArpeggio() { } -void Arpeggiator::processNote( notePlayHandle * _n ) +void InstrumentFunctionArpeggio::processNote( notePlayHandle * _n ) { const int base_note_key = _n->key(); if( _n->isTopNote() == false || @@ -375,7 +373,7 @@ void Arpeggiator::processNote( notePlayHandle * _n ) } } - const ChordCreator::ChordTable & chord_table = ChordCreator::ChordTable::getInstance(); + const InstrumentFunctionNoteStacking::ChordTable & chord_table = InstrumentFunctionNoteStacking::ChordTable::getInstance(); const int cur_chord_size = chord_table[selected_arp].size(); const int range = (int)( cur_chord_size * m_arpRangeModel.value() ); const int total_range = range * cnphv.size(); @@ -479,7 +477,7 @@ void Arpeggiator::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 ), @@ -512,7 +510,7 @@ void Arpeggiator::processNote( notePlayHandle * _n ) -void Arpeggiator::saveSettings( QDomDocument & _doc, QDomElement & _this ) +void InstrumentFunctionArpeggio::saveSettings( QDomDocument & _doc, QDomElement & _this ) { m_arpEnabledModel.saveSettings( _doc, _this, "arp-enabled" ); m_arpModel.saveSettings( _doc, _this, "arp" ); @@ -527,7 +525,7 @@ void Arpeggiator::saveSettings( QDomDocument & _doc, QDomElement & _this ) -void Arpeggiator::loadSettings( const QDomElement & _this ) +void InstrumentFunctionArpeggio::loadSettings( const QDomElement & _this ) { m_arpEnabledModel.loadSettings( _this, "arp-enabled" ); m_arpModel.loadSettings( _this, "arp" ); diff --git a/src/core/InstrumentSoundShaping.cpp b/src/core/InstrumentSoundShaping.cpp index 535a0d99d..16a6f5050 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/LfoController.cpp b/src/core/LfoController.cpp index a189d500e..fa14c8b2d 100644 --- a/src/core/LfoController.cpp +++ b/src/core/LfoController.cpp @@ -49,7 +49,8 @@ LfoController::LfoController( Model * _parent ) : m_duration( 1000 ), m_phaseCorrection( 0 ), m_phaseOffset( 0 ), - m_sampleFunction( &Oscillator::sinSample ) + m_sampleFunction( &Oscillator::sinSample ), + m_userDefSampleBuffer( new SampleBuffer ) { connect( &m_waveModel, SIGNAL( dataChanged() ), @@ -61,6 +62,7 @@ LfoController::LfoController( Model * _parent ) : LfoController::~LfoController() { + sharedObject::unref( m_userDefSampleBuffer ); m_baseModel.disconnect( this ); m_speedModel.disconnect( this ); m_amountModel.disconnect( this ); @@ -164,7 +166,9 @@ float LfoController::value( int _offset ) // 44100 frames/sec return m_baseModel.value() + ( m_amountModel.value() * - m_sampleFunction(sampleFrame) + ( m_sampleFunction != NULL ? + m_sampleFunction(sampleFrame): + m_userDefSampleBuffer->userWaveSample(sampleFrame) ) / 2.0f ); } @@ -196,6 +200,14 @@ void LfoController::updateSampleFunction() case Oscillator::WhiteNoise: m_sampleFunction = &Oscillator::noiseSample; break; + case Oscillator::UserDefinedWave: + m_sampleFunction = NULL; + /*TODO: If C++11 is allowed, should change the type of + m_sampleFunction be std::function + and use the line below: + */ + //m_sampleFunction = &(m_userDefSampleBuffer->userWaveSample) + break; } } diff --git a/src/core/Piano.cpp b/src/core/Piano.cpp index 3bd85ee8d..584362f46 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 24e047d99..0128444e8 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 3308faf60..674a0a101 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -39,6 +38,7 @@ #include +#define OV_EXCLUDE_STATIC_CALLBACKS #ifdef LMMS_HAVE_OGGVORBIS #include #endif @@ -61,6 +61,8 @@ #include "interpolation.h" #include "templates.h" +#include "FileDialog.h" + SampleBuffer::SampleBuffer( const QString & _audio_file, bool _is_base64_data ) : @@ -829,10 +831,7 @@ void SampleBuffer::visualize( QPainter & _p, const QRect & _dr, QString SampleBuffer::openAudioFile() const { - QFileDialog ofd( NULL, tr( "Open audio file" ) ); -#if QT_VERSION >= 0x040806 - ofd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif + FileDialog ofd( NULL, tr( "Open audio file" ) ); QString dir; if( !m_audioFile.isEmpty() ) @@ -855,7 +854,7 @@ QString SampleBuffer::openAudioFile() const } // change dir to position of previously opened file ofd.setDirectory( dir ); - ofd.setFileMode( QFileDialog::ExistingFiles ); + ofd.setFileMode( FileDialog::ExistingFiles ); // set filters QStringList types; @@ -894,6 +893,23 @@ QString SampleBuffer::openAudioFile() const } + + +QString SampleBuffer::openAndSetAudioFile() +{ + QString fileName = this->openAudioFile(); + + if(!fileName.isEmpty()) + { + this->setAudioFile( fileName ); + } + + return fileName; +} + + + + #undef LMMS_HAVE_FLAC_STREAM_ENCODER_H /* not yet... */ #undef LMMS_HAVE_FLAC_STREAM_DECODER_H diff --git a/src/core/SampleRecordHandle.cpp b/src/core/SampleRecordHandle.cpp index 9d0cff4ad..674af8d93 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 d199f8454..0cbcef43b 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 95b351197..662dc43ea 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 8e3895d24..673d5f20d 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 d323e6e7f..5e65b5cd0 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 eb6949356..ffa2c97dd 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 dc06db891..799d7f5df 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 2d77f0237..ce86cb9c0 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 9654cde23..16ce402fe 100644 --- a/src/core/note_play_handle.cpp +++ b/src/core/note_play_handle.cpp @@ -2,7 +2,7 @@ * note_play_handle.cpp - implementation of class notePlayHandle, part of * rendering 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 * @@ -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 ); - - if( !isTopNote() || !instrumentTrack()->isArpeggiatorEnabled() ) + // inform attached components about new MIDI note (used for recording in Piano Roll) + if( m_origin == OriginMidiInput ) { - // send MIDI-note-on-event - m_instrumentTrack->processOutEvent( midiEvent( MidiNoteOn, - m_instrumentTrack->midiPort()->realOutputChannel(), - midiKey(), midiVelocity() ), - midiTime::fromFrames( offset(), - engine::framesPerTick() ) ); + m_instrumentTrack->midiNoteOn( *this ); + } + + if( !isTopNote() || !instrumentTrack()->isArpeggioEnabled() ) + { + // 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 @@ -339,14 +366,12 @@ void notePlayHandle::noteOff( const f_cnt_t _s ) m_releaseFramesToDo = qMax( 0, // 10, m_instrumentTrack->m_soundShaping.releaseFrames() ); - if( !isTopNote() || !instrumentTrack()->isArpeggiatorEnabled() ) + 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; @@ -387,8 +412,7 @@ float notePlayHandle::volumeLevel( const f_cnt_t _frame ) bool notePlayHandle::isArpeggioBaseNote() const { - return isTopNote() && ( m_partOfArpeggio || - m_instrumentTrack->isArpeggiatorEnabled() ); + return isTopNote() && ( m_partOfArpeggio || m_instrumentTrack->isArpeggioEnabled() ); } @@ -502,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/song.cpp b/src/core/song.cpp index ab787ceba..4235b1dd8 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -47,6 +46,7 @@ #include "ImportFilter.h" #include "InstrumentTrack.h" #include "MainWindow.h" +#include "FileDialog.h" #include "MidiClient.h" #include "mmp.h" #include "note_play_handle.h" @@ -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 ) @@ -1310,7 +1310,7 @@ bool song::guiSaveProjectAs( const QString & _file_name ) void song::importProject() { - QFileDialog ofd( NULL, tr( "Import file" ), + FileDialog ofd( NULL, tr( "Import file" ), configManager::inst()->userProjectsDir(), tr("MIDI sequences") + " (*.mid *.midi *.rmi);;" + @@ -1320,11 +1320,8 @@ void song::importProject() " (*.h2song);;" + tr("All file types") + " (*.*)"); -#if QT_VERSION >= 0x040806 - ofd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif - ofd.setFileMode( QFileDialog::ExistingFiles ); + ofd.setFileMode( FileDialog::ExistingFiles ); if( ofd.exec () == QDialog::Accepted && !ofd.selectedFiles().isEmpty() ) { ImportFilter::import( ofd.selectedFiles()[0], this ); @@ -1377,13 +1374,10 @@ void song::exportProject(bool multiExport) return; } - QFileDialog efd( engine::mainWindow() ); -#if QT_VERSION >= 0x040806 - efd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif + FileDialog efd( engine::mainWindow() ); if (multiExport) { - efd.setFileMode( QFileDialog::Directory); + efd.setFileMode( FileDialog::Directory); efd.setWindowTitle( tr( "Select directory for writing exported tracks..." ) ); if( !m_fileName.isEmpty() ) { @@ -1392,7 +1386,7 @@ void song::exportProject(bool multiExport) } else { - efd.setFileMode( QFileDialog::AnyFile ); + efd.setFileMode( FileDialog::AnyFile ); int idx = 0; QStringList types; while( __fileEncodeDevices[idx].m_fileFormat != @@ -1417,7 +1411,7 @@ void song::exportProject(bool multiExport) efd.setWindowTitle( tr( "Select file for project-export..." ) ); } - efd.setAcceptMode( QFileDialog::AcceptSave ); + efd.setAcceptMode( FileDialog::AcceptSave ); if( efd.exec() == QDialog::Accepted && diff --git a/src/core/timeline.cpp b/src/core/timeline.cpp index d392ff8c4..3c0aa6f11 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] ); @@ -301,13 +301,20 @@ void timeLine::mousePressEvent( QMouseEvent* event ) m_loopPos[( m_action == MoveLoopBegin ) ? 0 : 1] = t; } - if( m_action == MoveLoopBegin || m_action == MoveLoopEnd ) + if( m_action == MoveLoopBegin ) { delete m_hint; m_hint = textFloat::displayMessage( tr( "Hint" ), tr( "Press to disable magnetic loop points." ), embed::getIconPixmap( "hint" ), 0 ); } + else if( m_action == MoveLoopEnd ) + { + delete m_hint; + m_hint = textFloat::displayMessage( tr( "Hint" ), + tr( "Hold to move the begin loop point; Press to disable magnetic loop points." ), + embed::getIconPixmap( "hint" ), 0 ); + } mouseMoveEvent( event ); } @@ -317,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 ) { @@ -349,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 10a4ed80f..f11210e27 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 ce3847f0e..f7a25ec7b 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 cd0127b36..e66c728b4 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 5e2903f68..66fed87d3 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 02d5fb178..2ff35c9a0 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/LfoControllerDialog.cpp b/src/gui/LfoControllerDialog.cpp index 05458085e..3aa9f7c0a 100644 --- a/src/gui/LfoControllerDialog.cpp +++ b/src/gui/LfoControllerDialog.cpp @@ -178,15 +178,17 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent toolTip::add( white_noise_btn, tr( "Click here for white-noise." ) ); - pixmapButton * uwb = new pixmapButton( this, NULL ); - uwb->move( CD_LFO_SHAPES_X + 45, CD_LFO_SHAPES_Y + 15 ); - uwb->setActiveGraphic( embed::getIconPixmap( + m_userWaveBtn = new pixmapButton( this, NULL ); + m_userWaveBtn->move( CD_LFO_SHAPES_X + 45, CD_LFO_SHAPES_Y + 15 ); + m_userWaveBtn->setActiveGraphic( embed::getIconPixmap( "usr_wave_active" ) ); - uwb->setInactiveGraphic( embed::getIconPixmap( + m_userWaveBtn->setInactiveGraphic( embed::getIconPixmap( "usr_wave_inactive" ) ); - uwb->setEnabled( false ); - toolTip::add( uwb, tr( "Click here for a user-defined " - "shape." ) ); + connect( m_userWaveBtn, + SIGNAL( doubleClicked() ), + this, SLOT( askUserDefWave() ) ); + toolTip::add( m_userWaveBtn, + tr( "Click here for a user-defined shape.\nDouble click to pick a file." ) ); m_waveBtnGrp = new automatableButtonGroup( this ); m_waveBtnGrp->addButton( sin_wave_btn ); @@ -196,7 +198,7 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent m_waveBtnGrp->addButton( moog_saw_wave_btn ); m_waveBtnGrp->addButton( exp_wave_btn ); m_waveBtnGrp->addButton( white_noise_btn ); - m_waveBtnGrp->addButton( uwb ); + m_waveBtnGrp->addButton( m_userWaveBtn ); pixmapButton * x1 = new pixmapButton( this, NULL ); @@ -240,11 +242,26 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent LfoControllerDialog::~LfoControllerDialog() { + m_userWaveBtn->disconnect( this ); //delete m_subWindow; } +void LfoControllerDialog::askUserDefWave() +{ + SampleBuffer * sampleBuffer = dynamic_cast(this->model())-> + m_userDefSampleBuffer; + QString fileName = sampleBuffer->openAndSetAudioFile(); + if( fileName.isEmpty() == false ) + { + // TODO: + toolTip::add( m_userWaveBtn, sampleBuffer->audioFile() ); + } +} + + + void LfoControllerDialog::contextMenuEvent( QContextMenuEvent * ) { /* diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 30fa8d925..c86975b3f 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -62,6 +61,8 @@ #include "ProjectJournal.h" #include "AutomationEditor.h" #include "templates.h" +#include "FileDialog.h" +#include "VersionedSaveDialog.h" @@ -242,6 +243,10 @@ void MainWindow::finalize( void ) this, SLOT( saveProject() ), Qt::CTRL + Qt::Key_S ); + project_menu->addAction( embed::getIconPixmap( "project_save" ), + tr( "Save as new &version" ), + this, SLOT( saveProjectAsNewVersion() ), + Qt::CTRL + Qt::ALT + Qt::Key_S ); project_menu->addAction( embed::getIconPixmap( "project_saveas" ), tr( "Save &As..." ), this, SLOT( saveProjectAs() ), @@ -270,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 ); @@ -278,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() ) ); @@ -407,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() ), @@ -681,18 +686,15 @@ void MainWindow::createNewProjectFromTemplate( QAction * _idx ) - void MainWindow::openProject( void ) { if( mayChangeProject() ) { - QFileDialog ofd( this, tr( "Open project" ), "", + FileDialog ofd( this, tr( "Open project" ), "", tr( "MultiMedia Project (*.mmp *.mmpz *.xml)" ) ); -#if QT_VERSION >= 0x040806 - ofd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif + ofd.setDirectory( configManager::inst()->userProjectsDir() ); - ofd.setFileMode( QFileDialog::ExistingFiles ); + ofd.setFileMode( FileDialog::ExistingFiles ); if( ofd.exec () == QDialog::Accepted && !ofd.selectedFiles().isEmpty() ) { @@ -751,14 +753,9 @@ bool MainWindow::saveProject( void ) bool MainWindow::saveProjectAs( void ) { - QFileDialog sfd( this, tr( "Save project" ), "", + VersionedSaveDialog sfd( this, tr( "Save project" ), "", tr( "MultiMedia Project (*.mmp *.mmpz);;" "MultiMedia Project Template (*.mpt)" ) ); -#if QT_VERSION >= 0x040806 - sfd.setOption( QFileDialog::DontUseCustomDirectoryIcons ); -#endif - sfd.setAcceptMode( QFileDialog::AcceptSave ); - sfd.setFileMode( QFileDialog::AnyFile ); QString f = engine::getSong()->projectFileName(); if( f != "" ) { @@ -770,7 +767,7 @@ bool MainWindow::saveProjectAs( void ) sfd.setDirectory( configManager::inst()->userProjectsDir() ); } - if( sfd.exec () == QFileDialog::Accepted && + if( sfd.exec () == FileDialog::Accepted && !sfd.selectedFiles().isEmpty() && sfd.selectedFiles()[0] != "" ) { engine::getSong()->guiSaveProjectAs( @@ -783,6 +780,24 @@ bool MainWindow::saveProjectAs( void ) +bool MainWindow::saveProjectAsNewVersion( void ) +{ + QString fileName = engine::getSong()->projectFileName(); + if( fileName == "" ) + { + return saveProjectAs(); + } + else + { + VersionedSaveDialog::changeFileNameVersion( fileName, true ); + engine::getSong()->guiSaveProjectAs( fileName ); + return true; + } +} + + + + void MainWindow::showSettingsDialog( void ) { setupDialog sd; diff --git a/src/gui/PianoView.cpp b/src/gui/PianoView.cpp index 18a916a1e..021964b50 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 214d802a1..11a91727d 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 41a502696..94b6fb217 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 ). @@ -79,7 +79,19 @@ aboutDialog::aboutDialog() : authorLabel->setPlainText( embed::getText( "AUTHORS" ) ); licenseLabel->setPlainText( embed::getText( "COPYING" ) ); + + QString contText = embed::getText( "CONTRIBUTORS" ); + if ( contText.length() >= 2 ) + { + QWidget *widget = new QWidget(); + QVBoxLayout *layout = new QVBoxLayout(); + QTextEdit *contWidget = new QTextEdit(); + contWidget->setReadOnly(true); + contWidget->setText( contText ); + + layout->addWidget( new QLabel( tr("Contributors ordered by number of commits:"), this ) ); + layout->addWidget( contWidget ); + widget->setLayout( layout ); + tabWidget->insertTab( 2, widget, tr("Involved") ); + } } - - - diff --git a/src/gui/bb_editor.cpp b/src/gui/bb_editor.cpp index a26094e80..ec6de9034 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 new file mode 100644 index 000000000..ad77018cc --- /dev/null +++ b/src/gui/dialogs/FileDialog.cpp @@ -0,0 +1,68 @@ +/* + * FileDialog.cpp - implementation of class FileDialog + * + * Copyright (c) 2014 Lukas W + * + * 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. + * + */ + +#include +#include +#include +#include + +#include "config_mgr.h" +#include "FileDialog.h" + + +FileDialog::FileDialog( QWidget *parent, const QString &caption, + const QString &directory, const QString &filter ) : + QFileDialog( parent, caption, directory, filter ) +{ +#if QT_VERSION >= 0x040806 + setOption( QFileDialog::DontUseCustomDirectoryIcons ); +#endif + + // Add additional locations to the sidebar + QList urls = sidebarUrls(); + urls << QUrl::fromLocalFile( QDesktopServices::storageLocation( QDesktopServices::DesktopLocation ) ); + // Find downloads directory + QDir downloadDir( QDir::homePath() + "/Downloads" ); + if ( ! downloadDir.exists() ) + downloadDir = QDesktopServices::storageLocation( QDesktopServices::DocumentsLocation ) + "/Downloads"; + if ( downloadDir.exists() ) + urls << QUrl::fromLocalFile( downloadDir.absolutePath() ); + + urls << QUrl::fromLocalFile( QDesktopServices::storageLocation( QDesktopServices::MusicLocation ) ); + urls << QUrl::fromLocalFile( configManager::inst()->workingDir() ); + + setSidebarUrls(urls); +} + + + +void FileDialog::clearSelection() +{ + QListView *view = findChild(); + Q_ASSERT( view ); + view->clearSelection(); +} + + +#include "moc_FileDialog.cxx" diff --git a/src/gui/dialogs/VersionedSaveDialog.cpp b/src/gui/dialogs/VersionedSaveDialog.cpp new file mode 100644 index 000000000..c52f47dc2 --- /dev/null +++ b/src/gui/dialogs/VersionedSaveDialog.cpp @@ -0,0 +1,139 @@ +/* + * VersionedSaveDialog.cpp - implementation of class VersionedSaveDialog + * + * Copyright (c) 2014 Lukas W + * + * 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. + * + */ + + +#include +#include +#include +#include + +#include "VersionedSaveDialog.h" + + + + +VersionedSaveDialog::VersionedSaveDialog( QWidget *parent, + const QString &caption, + const QString &directory, + const QString &filter ) : + FileDialog(parent, caption, directory, filter) +{ + setAcceptMode( QFileDialog::AcceptSave ); + setFileMode( QFileDialog::AnyFile ); + + // Create + and - buttons + QPushButton *plusButton( new QPushButton( "+", this) ); + plusButton->setToolTip( tr( "Increment version number" ) ); + QPushButton *minusButton( new QPushButton( "-", this ) ); + minusButton->setToolTip( tr( "Decrement version number" ) ); + plusButton->setFixedWidth( plusButton->fontMetrics().width( "+" ) + 30 ); + minusButton->setFixedWidth( minusButton->fontMetrics().width( "+" ) + 30 ); + + // Add buttons to grid layout. For doing this, remove the lineEdit and + // replace it with a HBox containing lineEdit and the buttons. + QGridLayout *layout = dynamic_cast( this->layout() ); + QWidget *lineEdit = findChild(); + layout->removeWidget( lineEdit ); + + QHBoxLayout* hLayout( new QHBoxLayout() ); + hLayout->addWidget( lineEdit ); + hLayout->addWidget( plusButton ); + hLayout->addWidget( minusButton ); + layout->addLayout( hLayout, 2, 1 ); + + // Connect + and - buttons + connect( plusButton, SIGNAL( clicked() ), this, SLOT( incrementVersion() )); + connect( minusButton, SIGNAL( clicked() ), this, SLOT( decrementVersion() )); +} + + + + +bool VersionedSaveDialog::changeFileNameVersion(QString &fileName, bool increment ) +{ + static QRegExp regexp( "-\\d+(\\.\\w+)?$" ); + + int idx = regexp.indexIn( fileName ); + // For file names without extension (no ".mmpz") + int insertIndex = fileName.lastIndexOf( '.' ); + if ( insertIndex < idx+1 ) + insertIndex = fileName.size(); + + if ( idx == -1 ) + { + // Can't decrement if there is no version number + if ( increment == false ) + return false; + else + fileName.insert( insertIndex, "-01" ); + } + else + { + // Find current version number + QString number = fileName.mid( idx+1, insertIndex - idx - 1 ); + bool ok; + ushort version = number.toUShort( &ok ); + Q_ASSERT( ok ); + + // Can't decrement 0 + if ( !increment and version == 0 ) + return false; + // Replace version number + version = increment ? version + 1 : version - 1; + QString newnumber = QString( "%1" ).arg( version, 2, 10, QChar( '0' ) ); + + fileName.replace( idx+1, number.length(), newnumber ); + } + return true; +} + + + + +void VersionedSaveDialog::incrementVersion() +{ + const QStringList& selected = selectedFiles(); + if ( selected.size() != 1 ) + return; + QString file = selected[0]; + changeFileNameVersion( file, true ); + clearSelection(); + selectFile( file ); +} + + + + +void VersionedSaveDialog::decrementVersion() +{ + const QStringList& selected = selectedFiles(); + if ( selected.size() != 1 ) + return; + QString file = selected[0]; + changeFileNameVersion( file, false ); + clearSelection(); + selectFile( file ); +} + +#include "moc_VersionedSaveDialog.cxx" diff --git a/src/gui/dialogs/about_dialog.ui b/src/gui/dialogs/about_dialog.ui index b795fd0f8..39c1974b9 100644 --- a/src/gui/dialogs/about_dialog.ui +++ b/src/gui/dialogs/about_dialog.ui @@ -1,3 +1,4 @@ + AboutDialog @@ -125,7 +126,7 @@ - Copyright (c) 2004-2013, LMMS developers + Copyright (c) 2004-2014, LMMS developers true @@ -151,7 +152,7 @@ - http://lmms.sourceforge.net + <html><head/><body><p><a href="http://lmms.sourceforge.net"><span style=" text-decoration: underline; color:#0000ff;">http://lmms.sourceforge.net</span></a></p></body></html> true diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp index 27ebbcace..4a9d8203e 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. " @@ -520,7 +525,7 @@ pianoRoll::pianoRoll() : this, SLOT( quantizeChanged() ) ); - const ChordCreator::ChordTable & chord_table = ChordCreator::ChordTable::getInstance(); + const InstrumentFunctionNoteStacking::ChordTable & chord_table = InstrumentFunctionNoteStacking::ChordTable::getInstance(); // setup scale-stuff QLabel * scale_lbl = new QLabel( m_toolBar ); @@ -644,7 +649,7 @@ void pianoRoll::changeNoteEditMode( int i ) void pianoRoll::markSemiTone( int i ) { const int key = getKey( mapFromGlobal( m_semiToneMarkerMenu->pos() ).y() ); - const ChordCreator::Chord * chord = 0; + const InstrumentFunctionNoteStacking::Chord * chord = 0; switch( static_cast( i ) ) { @@ -665,13 +670,13 @@ void pianoRoll::markSemiTone( int i ) break; } case stmaMarkCurrentScale: - chord = & ChordCreator::ChordTable::getInstance() + chord = & InstrumentFunctionNoteStacking::ChordTable::getInstance() .getScaleByName( m_scaleModel.currentText() ); case stmaMarkCurrentChord: { if( ! chord ) { - chord = & ChordCreator::ChordTable::getInstance() + chord = & InstrumentFunctionNoteStacking::ChordTable::getInstance() .getChordByName( m_chordModel.currentText() ); } @@ -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 ); @@ -1602,7 +1601,7 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) new_note.setVolume( m_lastNoteVolume ); created_new_note = m_pattern->addNote( new_note ); - const ChordCreator::Chord & chord = ChordCreator::ChordTable::getInstance() + const InstrumentFunctionNoteStacking::Chord & chord = InstrumentFunctionNoteStacking::ChordTable::getInstance() .getChordByName( m_chordModel.currentText() ); if( ! chord.isEmpty() ) @@ -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(); @@ -3855,10 +3849,10 @@ int pianoRoll::quantization() const void pianoRoll::updateSemiToneMarkerMenu() { - const ChordCreator::Chord & scale = ChordCreator::ChordTable::getInstance() + const InstrumentFunctionNoteStacking::Chord & scale = InstrumentFunctionNoteStacking::ChordTable::getInstance() .getScaleByName( m_scaleModel.currentText() ); - const ChordCreator::Chord & chord = ChordCreator::ChordTable::getInstance() + const InstrumentFunctionNoteStacking::Chord & chord = InstrumentFunctionNoteStacking::ChordTable::getInstance() .getChordByName( m_chordModel.currentText() ); emit semiToneMarkerMenuScaleSetEnabled( ! scale.isEmpty() ); @@ -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/plugin_browser.cpp b/src/gui/plugin_browser.cpp index 1ecdebbb8..649f36add 100644 --- a/src/gui/plugin_browser.cpp +++ b/src/gui/plugin_browser.cpp @@ -35,6 +35,13 @@ #include "string_pair_drag.h" +bool pluginBefore( const Plugin::Descriptor& d1, const Plugin::Descriptor& d2 ) +{ + return qstricmp( d1.displayName, d2.displayName ) < 0 ? true : false; +} + + + pluginBrowser::pluginBrowser( QWidget * _parent ) : SideBarWidget( tr( "Instrument plugins" ), @@ -61,6 +68,7 @@ pluginBrowser::pluginBrowser( QWidget * _parent ) : view_layout->addWidget( hint ); Plugin::getDescriptorsOfAvailPlugins( m_pluginDescriptors ); + qSort( m_pluginDescriptors.begin(), m_pluginDescriptors.end(), pluginBefore ); for( Plugin::DescriptorList::ConstIterator it = m_pluginDescriptors.begin(); it != m_pluginDescriptors.end(); ++it ) diff --git a/src/gui/setup_dialog.cpp b/src/gui/setup_dialog.cpp index dcda537de..d863833b6 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 * @@ -23,7 +23,6 @@ */ #include -#include #include #include #include @@ -46,6 +45,7 @@ #include "tooltip.h" #include "led_checkbox.h" #include "lcd_spinbox.h" +#include "FileDialog.h" // platform-specific audio-interface-classes @@ -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; @@ -1056,13 +1013,8 @@ void setupDialog::toggleOneInstrumentTrackWindow( bool _enabled ) void setupDialog::openWorkingDir() { - QString new_dir = QFileDialog::getExistingDirectory( this, - tr( "Choose LMMS working directory" ), - m_workingDir -#if QT_VERSION >= 0x040806 - , QFileDialog::DontUseCustomDirectoryIcons -#endif - ); + QString new_dir = FileDialog::getExistingDirectory( this, + tr( "Choose LMMS working directory" ), m_workingDir ); if( new_dir != QString::null ) { m_wdLineEdit->setText( new_dir ); @@ -1082,7 +1034,7 @@ void setupDialog::setWorkingDir( const QString & _wd ) void setupDialog::openVSTDir() { - QString new_dir = QFileDialog::getExistingDirectory( this, + QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose your VST-plugin directory" ), m_vstDir ); if( new_dir != QString::null ) @@ -1104,7 +1056,7 @@ void setupDialog::setVSTDir( const QString & _vd ) void setupDialog::openArtworkDir() { - QString new_dir = QFileDialog::getExistingDirectory( this, + QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose artwork-theme directory" ), m_artworkDir ); if( new_dir != QString::null ) @@ -1126,7 +1078,7 @@ void setupDialog::setArtworkDir( const QString & _ad ) void setupDialog::openFLDir() { - QString new_dir = QFileDialog::getExistingDirectory( this, + QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose FL Studio installation directory" ), m_flDir ); if( new_dir != QString::null ) @@ -1140,7 +1092,7 @@ void setupDialog::openFLDir() void setupDialog::openLADSPADir() { - QString new_dir = QFileDialog::getExistingDirectory( this, + QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose LADSPA plugin directory" ), m_ladDir ); if( new_dir != QString::null ) @@ -1163,7 +1115,7 @@ void setupDialog::openLADSPADir() void setupDialog::openSTKDir() { #ifdef LMMS_HAVE_STK - QString new_dir = QFileDialog::getExistingDirectory( this, + QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose STK rawwave directory" ), m_stkDir ); if( new_dir != QString::null ) @@ -1179,7 +1131,7 @@ void setupDialog::openSTKDir() void setupDialog::openDefaultSoundfont() { #ifdef LMMS_HAVE_FLUIDSYNTH - QString new_file = QFileDialog::getOpenFileName( this, + QString new_file = FileDialog::getOpenFileName( this, tr( "Choose default SoundFont" ), m_defaultSoundfont, "SoundFont2 Files (*.sf2)" ); @@ -1212,7 +1164,7 @@ void setupDialog::openBackgroundArtwork() QString dir = ( m_backgroundArtwork.isEmpty() ) ? m_artworkDir : m_backgroundArtwork; - QString new_file = QFileDialog::getOpenFileName( this, + QString new_file = FileDialog::getOpenFileName( this, tr( "Choose background artwork" ), dir, "Image Files (" + fileTypes + ")" ); diff --git a/src/gui/song_editor.cpp b/src/gui/song_editor.cpp index 60d7ed256..099204616 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 9b6b8cc05..d61adc966 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/InstrumentFunctionViews.cpp b/src/gui/widgets/InstrumentFunctionViews.cpp index 1e8e29ad3..e2305906e 100644 --- a/src/gui/widgets/InstrumentFunctionViews.cpp +++ b/src/gui/widgets/InstrumentFunctionViews.cpp @@ -23,6 +23,7 @@ */ #include +#include #include "InstrumentFunctions.h" #include "InstrumentFunctionViews.h" @@ -37,50 +38,43 @@ #include "tooltip.h" - -const int CHORDS_GROUPBOX_X = 4; -const int CHORDS_GROUPBOX_Y = 5; -const int CHORDS_GROUPBOX_WIDTH = 242; -const int CHORDS_GROUPBOX_HEIGHT = 65; -const int ARP_GROUPBOX_X = CHORDS_GROUPBOX_X; -const int ARP_GROUPBOX_Y = 10 + CHORDS_GROUPBOX_Y + CHORDS_GROUPBOX_HEIGHT; -const int ARP_GROUPBOX_WIDTH = CHORDS_GROUPBOX_WIDTH; -const int ARP_GROUPBOX_HEIGHT = 240 - ARP_GROUPBOX_Y; - - - -ChordCreatorView::ChordCreatorView( ChordCreator * _cc, QWidget * _parent ) : - QWidget( _parent ), +InstrumentFunctionNoteStackingView::InstrumentFunctionNoteStackingView( InstrumentFunctionNoteStacking* cc, QWidget* parent ) : + QWidget( parent ), ModelView( NULL, this ), - m_cc( _cc ), - m_chordsGroupBox( new groupBox( tr( "CHORDS" ), this ) ), - m_chordsComboBox( new comboBox( m_chordsGroupBox ) ), - m_chordRangeKnob( new knob( knobBright_26, m_chordsGroupBox ) ) + m_cc( cc ), + m_chordsGroupBox( new groupBox( tr( "STACKING" ) ) ), + m_chordsComboBox( new comboBox() ), + m_chordRangeKnob( new knob( knobBright_26 ) ) { - move( CHORDS_GROUPBOX_X, CHORDS_GROUPBOX_Y ); - setFixedSize( 250, CHORDS_GROUPBOX_HEIGHT ); - m_chordsGroupBox->setGeometry( 0, 0, CHORDS_GROUPBOX_WIDTH, - CHORDS_GROUPBOX_HEIGHT ); + QHBoxLayout* topLayout = new QHBoxLayout( this ); + topLayout->setMargin( 0 ); + topLayout->addWidget( m_chordsGroupBox ); + QGridLayout* mainLayout = new QGridLayout( m_chordsGroupBox ); + mainLayout->setContentsMargins( 8, 18, 8, 8 ); + mainLayout->setColumnStretch( 0, 1 ); + mainLayout->setHorizontalSpacing( 20 ); + mainLayout->setVerticalSpacing( 1 ); - m_chordsComboBox->setGeometry( 10, 25, 140, 22 ); - + QLabel* chordLabel = new QLabel( tr( "Chord:" ) ); + chordLabel->setFont( pointSize<8>( chordLabel->font() ) ); m_chordRangeKnob->setLabel( tr( "RANGE" ) ); - m_chordRangeKnob->move( 164, 24 ); - m_chordRangeKnob->setHintText( tr( "Chord range:" ) + " ", " " + - tr( "octave(s)" ) ); + m_chordRangeKnob->setHintText( tr( "Chord range:" ) + " ", " " + tr( "octave(s)" ) ); m_chordRangeKnob->setWhatsThis( tr( "Use this knob for setting the chord range in octaves. " "The selected chord will be played within specified " "number of octaves." ) ); + mainLayout->addWidget( chordLabel, 0, 0 ); + mainLayout->addWidget( m_chordsComboBox, 1, 0 ); + mainLayout->addWidget( m_chordRangeKnob, 0, 1, 2, 1, Qt::AlignHCenter ); } -ChordCreatorView::~ChordCreatorView() +InstrumentFunctionNoteStackingView::~InstrumentFunctionNoteStackingView() { delete m_chordsGroupBox; } @@ -88,9 +82,9 @@ ChordCreatorView::~ChordCreatorView() -void ChordCreatorView::modelChanged() +void InstrumentFunctionNoteStackingView::modelChanged() { - m_cc = castModel(); + m_cc = castModel(); m_chordsGroupBox->setModel( &m_cc->m_chordsEnabledModel ); m_chordsComboBox->setModel( &m_cc->m_chordsModel ); m_chordRangeKnob->setModel( &m_cc->m_chordRangeModel ); @@ -102,22 +96,27 @@ void ChordCreatorView::modelChanged() -ArpeggiatorView::ArpeggiatorView( Arpeggiator * _arp, QWidget * _parent ) : - QWidget( _parent ), +InstrumentFunctionArpeggioView::InstrumentFunctionArpeggioView( InstrumentFunctionArpeggio* arp, QWidget* parent ) : + QWidget( parent ), ModelView( NULL, this ), - m_a( _arp ), - m_arpGroupBox( new groupBox( tr( "ARPEGGIO" ), this ) ), - m_arpComboBox( new comboBox( m_arpGroupBox) ), - m_arpRangeKnob( new knob( knobBright_26, m_arpGroupBox ) ), - m_arpTimeKnob( new TempoSyncKnob( knobBright_26, m_arpGroupBox ) ), - m_arpGateKnob( new knob( knobBright_26, m_arpGroupBox ) ), - m_arpDirectionComboBox( new comboBox( m_arpGroupBox ) ), - m_arpModeComboBox( new comboBox( m_arpGroupBox ) ) + m_a( arp ), + m_arpGroupBox( new groupBox( tr( "ARPEGGIO" ) ) ), + m_arpComboBox( new comboBox() ), + m_arpRangeKnob( new knob( knobBright_26 ) ), + m_arpTimeKnob( new TempoSyncKnob( knobBright_26 ) ), + m_arpGateKnob( new knob( knobBright_26 ) ), + m_arpDirectionComboBox( new comboBox() ), + m_arpModeComboBox( new comboBox() ) { - move( ARP_GROUPBOX_X, ARP_GROUPBOX_Y ); - setFixedSize( 250, ARP_GROUPBOX_HEIGHT ); - m_arpGroupBox->setGeometry( 0, 0, ARP_GROUPBOX_WIDTH, - ARP_GROUPBOX_HEIGHT ); + QHBoxLayout* topLayout = new QHBoxLayout( this ); + topLayout->setMargin( 0 ); + topLayout->addWidget( m_arpGroupBox ); + + QGridLayout* mainLayout = new QGridLayout( m_arpGroupBox ); + mainLayout->setContentsMargins( 8, 18, 8, 8 ); + mainLayout->setColumnStretch( 0, 1 ); + mainLayout->setHorizontalSpacing( 20 ); + mainLayout->setVerticalSpacing( 1 ); m_arpGroupBox->setWhatsThis( tr( "An arpeggio is a method playing (especially plucked) " @@ -130,13 +129,8 @@ ArpeggiatorView::ArpeggiatorView( Arpeggiator * _arp, QWidget * _parent ) : "possible chords, you can select." ) ); - m_arpComboBox->setGeometry( 10, 25, 140, 22 ); - - m_arpRangeKnob->setLabel( tr( "RANGE" ) ); - m_arpRangeKnob->move( 164, 24 ); - m_arpRangeKnob->setHintText( tr( "Arpeggio range:" ) + " ", " " + - tr( "octave(s)" ) ); + m_arpRangeKnob->setHintText( tr( "Arpeggio range:" ) + " ", " " + tr( "octave(s)" ) ); m_arpRangeKnob->setWhatsThis( tr( "Use this knob for setting the arpeggio range in octaves. " "The selected arpeggio will be played within specified " @@ -144,9 +138,7 @@ ArpeggiatorView::ArpeggiatorView( Arpeggiator * _arp, QWidget * _parent ) : m_arpTimeKnob->setLabel( tr( "TIME" ) ); - m_arpTimeKnob->move( 164, 70 ); - m_arpTimeKnob->setHintText( tr( "Arpeggio time:" ) + " ", " " + - tr( "ms" ) ); + m_arpTimeKnob->setHintText( tr( "Arpeggio time:" ) + " ", " " + tr( "ms" ) ); m_arpTimeKnob->setWhatsThis( tr( "Use this knob for setting the arpeggio time in " "milliseconds. The arpeggio time specifies how long " @@ -154,7 +146,6 @@ ArpeggiatorView::ArpeggiatorView( Arpeggiator * _arp, QWidget * _parent ) : m_arpGateKnob->setLabel( tr( "GATE" ) ); - m_arpGateKnob->move( 204, 70 ); m_arpGateKnob->setHintText( tr( "Arpeggio gate:" ) + " ", tr( "%" ) ); m_arpGateKnob->setWhatsThis( tr( "Use this knob for setting the arpeggio gate. The " @@ -162,24 +153,34 @@ ArpeggiatorView::ArpeggiatorView( Arpeggiator * _arp, QWidget * _parent ) : "arpeggio-tone that should be played. With this you " "can make cool staccato arpeggios." ) ); - m_arpDirectionLbl = new QLabel( tr( "Direction:" ), m_arpGroupBox ); - m_arpDirectionLbl->setGeometry( 10, 60, 64, 10 ); - m_arpDirectionLbl->setFont( pointSize<8>( m_arpDirectionLbl->font() ) ); + QLabel* arpChordLabel = new QLabel( tr( "Chord:" ) ); + arpChordLabel->setFont( pointSize<8>( arpChordLabel->font() ) ); - m_arpDirectionComboBox->setGeometry( 10, 74, 140, 22 ); + QLabel* arpDirectionLabel = new QLabel( tr( "Direction:" ) ); + arpDirectionLabel->setFont( pointSize<8>( arpDirectionLabel->font() ) ); + QLabel* arpModeLabel = new QLabel( tr( "Mode:" ) ); + arpModeLabel->setFont( pointSize<8>( arpModeLabel->font() ) ); - QLabel * mode_lbl = new QLabel( tr( "Mode:" ), m_arpGroupBox ); - mode_lbl->setGeometry( 10, 110, 64, 10 ); - mode_lbl->setFont( pointSize<8>( mode_lbl->font() ) ); + mainLayout->addWidget( arpChordLabel, 0, 0 ); + mainLayout->addWidget( m_arpComboBox, 1, 0 ); + mainLayout->addWidget( arpDirectionLabel, 3, 0 ); + mainLayout->addWidget( m_arpDirectionComboBox, 4, 0 ); + mainLayout->addWidget( arpModeLabel, 6, 0 ); + mainLayout->addWidget( m_arpModeComboBox, 7, 0 ); - m_arpModeComboBox->setGeometry( 10, 124, 128, 22 ); + mainLayout->addWidget( m_arpRangeKnob, 0, 1, 2, 1, Qt::AlignHCenter ); + mainLayout->addWidget( m_arpTimeKnob, 3, 1, 2, 1, Qt::AlignHCenter ); + mainLayout->addWidget( m_arpGateKnob, 6, 1, 2, 1, Qt::AlignHCenter ); + + mainLayout->setRowMinimumHeight( 2, 10 ); + mainLayout->setRowMinimumHeight( 5, 10 ); } -ArpeggiatorView::~ArpeggiatorView() +InstrumentFunctionArpeggioView::~InstrumentFunctionArpeggioView() { delete m_arpGroupBox; } @@ -187,9 +188,9 @@ ArpeggiatorView::~ArpeggiatorView() -void ArpeggiatorView::modelChanged() +void InstrumentFunctionArpeggioView::modelChanged() { - m_a = castModel(); + m_a = castModel(); m_arpGroupBox->setModel( &m_a->m_arpEnabledModel ); m_arpComboBox->setModel( &m_a->m_arpModel ); m_arpRangeKnob->setModel( &m_a->m_arpRangeModel ); diff --git a/src/gui/widgets/combobox.cpp b/src/gui/widgets/combobox.cpp index 9244344b9..c78e59ff7 100644 --- a/src/gui/widgets/combobox.cpp +++ b/src/gui/widgets/combobox.cpp @@ -1,7 +1,7 @@ /* - * combobox.cpp - implementation of LMMS-combobox + * combobox.cpp - implementation of LMMS combobox * - * Copyright (c) 2006-2011 Tobias Doerffel + * Copyright (c) 2006-2014 Tobias Doerffel * Copyright (c) 2008-2009 Paul Giblock * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -88,6 +88,22 @@ comboBox::~comboBox() +QSize comboBox::sizeHint() const +{ + int maxTextWidth = 0; + for( int i = 0; i < model()->size(); ++i ) + { + int w = fontMetrics().width( model()->itemText( i ) ); + if( w > maxTextWidth ) + { + maxTextWidth = w; + } + } + + return QSize( 32 + maxTextWidth, 22 ); +} + + void comboBox::contextMenuEvent( QContextMenuEvent * _me ) { diff --git a/src/gui/widgets/cpuload_widget.cpp b/src/gui/widgets/cpuload_widget.cpp index 508581a74..f634a6b1e 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 b9f301663..f2dc4c5fd 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/graph.cpp b/src/gui/widgets/graph.cpp index 538bb2544..9a4347647 100644 --- a/src/gui/widgets/graph.cpp +++ b/src/gui/widgets/graph.cpp @@ -482,6 +482,25 @@ void graphModel::setWaveToNoise() emit samplesChanged( 0, length() - 1 ); }; +QString graphModel::setWaveToUser() +{ + SampleBuffer * sampleBuffer = new SampleBuffer; + QString fileName = sampleBuffer->openAndSetAudioFile(); + if( fileName.isEmpty() == false ) + { + for( int i = 0; i < length(); i++ ) + { + m_samples[i] = sampleBuffer->userWaveSample( + i / static_cast( length() ) ); + } + } + + sharedObject::unref( sampleBuffer ); + + emit samplesChanged( 0, length() - 1 ); + return fileName; +}; + void graphModel::smooth() diff --git a/src/gui/widgets/knob.cpp b/src/gui/widgets/knob.cpp index 1c8dc9eaf..e03d2a6fc 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 0080c090c..f26485701 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 7dee75d33..2f6eebe95 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 5988ba3c5..3353ae3eb 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 44e78341f..b7412f19f 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -38,6 +37,7 @@ #include #include +#include "FileDialog.h" #include "InstrumentTrack.h" #include "AudioPort.h" #include "AutomationPattern.h" @@ -103,13 +103,13 @@ 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 ), m_soundShaping( this ), - m_arpeggiator( this ), - m_chordCreator( this ), + m_arpeggio( this ), + m_noteStacking( this ), m_piano( this ) { m_pitchModel.setCenterValue( 0 ); @@ -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 ); } @@ -490,8 +425,8 @@ void InstrumentTrack::playNote( notePlayHandle * _n, { // arpeggio- and chord-widget has to do its work -> adding sub-notes // for chords/arpeggios - m_chordCreator.processNote( _n ); - m_arpeggiator.processNote( _n ); + m_noteStacking.processNote( _n ); + m_arpeggio.processNote( _n ); if( !_n->isArpeggioBaseNote() && m_instrument != NULL ) { @@ -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_chordCreator.saveState( _doc, _this ); - m_arpeggiator.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() ) @@ -842,13 +742,13 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & _this ) { m_soundShaping.restoreState( node.toElement() ); } - else if( m_chordCreator.nodeName() == node.nodeName() ) + else if( m_noteStacking.nodeName() == node.nodeName() ) { - m_chordCreator.restoreState( node.toElement() ); + m_noteStacking.restoreState( node.toElement() ); } - else if( m_arpeggiator.nodeName() == node.nodeName() ) + else if( m_arpeggio.nodeName() == node.nodeName() ) { - m_arpeggiator.restoreState( node.toElement() ); + m_arpeggio.restoreState( node.toElement() ); } else if( m_midiPort.nodeName() == node.nodeName() ) { @@ -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() ); } } @@ -1351,10 +1241,22 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : // create tab-widgets m_ssView = new InstrumentSoundShapingView( m_tabWidget ); + + // FUNC tab QWidget* instrumentFunctions = new QWidget( m_tabWidget ); - m_chordView = new ChordCreatorView( &m_track->m_chordCreator, instrumentFunctions ); - m_arpView= new ArpeggiatorView( &m_track->m_arpeggiator, instrumentFunctions ); + QVBoxLayout* instrumentFunctionsLayout = new QVBoxLayout( instrumentFunctions ); + instrumentFunctionsLayout->setMargin( 5 ); + m_noteStackingView = new InstrumentFunctionNoteStackingView( &m_track->m_noteStacking ); + m_arpeggioView = new InstrumentFunctionArpeggioView( &m_track->m_arpeggio ); + + instrumentFunctionsLayout->addWidget( m_noteStackingView ); + instrumentFunctionsLayout->addWidget( m_arpeggioView ); + instrumentFunctionsLayout->addStretch(); + + // MIDI tab m_midiView = new InstrumentMidiIOView( m_tabWidget ); + + // FX tab m_effectView = new EffectRackView( m_track->m_audioPort.effects(), m_tabWidget ); m_tabWidget->addTab( m_ssView, tr( "ENV/LFO" ), 1 ); @@ -1407,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; } @@ -1451,8 +1354,8 @@ void InstrumentTrackWindow::modelChanged() } m_ssView->setModel( &m_track->m_soundShaping ); - m_chordView->setModel( &m_track->m_chordCreator ); - m_arpView->setModel( &m_track->m_arpeggiator ); + m_noteStackingView->setModel( &m_track->m_noteStacking ); + m_arpeggioView->setModel( &m_track->m_arpeggio ); m_midiView->setModel( &m_track->m_midiPort ); m_effectView->setModel( m_track->m_audioPort.effects() ); updateName(); @@ -1463,28 +1366,27 @@ void InstrumentTrackWindow::modelChanged() void InstrumentTrackWindow::saveSettingsBtnClicked() { - QFileDialog 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( QFileDialog::AcceptSave ); - sfd.setDirectory( preset_root + m_track->instrumentName() ); - sfd.setFileMode( QFileDialog::AnyFile ); - if( sfd.exec () == QDialog::Accepted && - !sfd.selectedFiles().isEmpty() && sfd.selectedFiles()[0] != "" - ) + sfd.setAcceptMode( FileDialog::AcceptSave ); + sfd.setDirectory( presetRoot + m_track->instrumentName() ); + sfd.setFileMode( FileDialog::AnyFile ); + + 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]; @@ -1515,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 ); @@ -1528,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(); @@ -1555,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(); @@ -1566,6 +1467,7 @@ void InstrumentTrackWindow::closeEvent( QCloseEvent * _ce ) { hide(); } + m_itv->m_tlb->setFocus(); m_itv->m_tlb->setChecked( false ); } @@ -1573,7 +1475,7 @@ void InstrumentTrackWindow::closeEvent( QCloseEvent * _ce ) -void InstrumentTrackWindow::focusInEvent( QFocusEvent * ) +void InstrumentTrackWindow::focusInEvent( QFocusEvent* ) { m_pianoView->setFocus(); } @@ -1581,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" ) { @@ -1614,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 9b7e55eed..25f6eee3b 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 67b2c2b59..a2c041e57 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 611f18adc..95ab237aa 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;