Merge branch 'stable-1.2' into master (@liushuyu)

This commit is contained in:
Hyunin Song
2017-07-15 07:56:28 +09:00
113 changed files with 1513 additions and 609 deletions

View File

@@ -2,7 +2,7 @@
set -e
PACKAGES="cmake libsndfile-dev fftw3-dev libvorbis-dev libogg-dev
PACKAGES="cmake libsndfile-dev fftw3-dev libvorbis-dev libogg-dev libmp3lame-dev
libasound2-dev libjack-dev libsdl-dev libsamplerate0-dev libstk0-dev
libfluidsynth-dev portaudio19-dev wine-dev g++-multilib libfltk1.3-dev
libgig-dev libsoundio-dev"

View File

@@ -12,7 +12,7 @@ MINGW_PACKAGES="mingw32-x-sdl mingw32-x-libvorbis mingw32-x-fluidsynth mingw32-x
mingw32-x-glib2 mingw32-x-portaudio mingw32-x-libsndfile mingw32-x-fftw
mingw32-x-flac mingw32-x-fltk mingw32-x-libsamplerate
mingw32-x-pkgconfig mingw32-x-binutils mingw32-x-gcc mingw32-x-runtime
mingw32-x-libgig mingw32-x-libsoundio $MINGW_PACKAGES"
mingw32-x-libgig mingw32-x-libsoundio mingw32-x-lame $MINGW_PACKAGES"
export MINGW_PACKAGES

View File

@@ -15,7 +15,7 @@ MINGW_PACKAGES="mingw64-x-sdl mingw64-x-libvorbis mingw64-x-fluidsynth mingw64-x
mingw64-x-glib2 mingw64-x-portaudio mingw64-x-libsndfile
mingw64-x-fftw mingw64-x-flac mingw64-x-fltk mingw64-x-libsamplerate
mingw64-x-pkgconfig mingw64-x-binutils mingw64-x-gcc mingw64-x-runtime
mingw64-x-libgig mingw64-x-libsoundio $MINGW_PACKAGES"
mingw64-x-libgig mingw64-x-libsoundio mingw64-x-lame $MINGW_PACKAGES"
export MINGW_PACKAGES

View File

@@ -2,7 +2,7 @@
set -e
PACKAGES="cmake pkg-config fftw libogg libvorbis libsndfile libsamplerate jack sdl stk portaudio node fltk"
PACKAGES="cmake pkg-config fftw libogg libvorbis lame libsndfile libsamplerate jack sdl libgig libsoundio stk portaudio node fltk"
if [ "$QT5" ]; then
PACKAGES="$PACKAGES qt@5.5"

View File

@@ -9,6 +9,7 @@ IF(COMMAND CMAKE_POLICY)
CMAKE_POLICY(SET CMP0003 NEW)
IF (CMAKE_MAJOR_VERSION GREATER 2)
CMAKE_POLICY(SET CMP0026 OLD)
CMAKE_POLICY(SET CMP0050 OLD)
ENDIF()
ENDIF(COMMAND CMAKE_POLICY)
@@ -29,7 +30,7 @@ SET(PROJECT_COPYRIGHT "2008-${PROJECT_YEAR} ${PROJECT_AUTHOR}")
SET(VERSION_MAJOR "1")
SET(VERSION_MINOR "2")
SET(VERSION_RELEASE "0")
SET(VERSION_STAGE "rc2")
SET(VERSION_STAGE "rc3")
SET(VERSION_BUILD "0")
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}")
IF(VERSION_STAGE)
@@ -50,6 +51,7 @@ OPTION(WANT_CAPS "Include C* Audio Plugin Suite (LADSPA plugins)" ON)
OPTION(WANT_CARLA "Include Carla plugin" ON)
OPTION(WANT_CMT "Include Computer Music Toolkit LADSPA plugins" ON)
OPTION(WANT_JACK "Include JACK (Jack Audio Connection Kit) support" ON)
OPTION(WANT_MP3LAME "Include MP3/Lame support" ON)
OPTION(WANT_OGGVORBIS "Include OGG/Vorbis support" ON)
OPTION(WANT_PULSEAUDIO "Include PulseAudio support" ON)
OPTION(WANT_PORTAUDIO "Include PortAudio support" ON)
@@ -306,6 +308,21 @@ IF(NOT LMMS_HAVE_PULSEAUDIO)
ENDIF(NOT LMMS_HAVE_PULSEAUDIO)
# check for MP3/Lame-libraries
IF(WANT_MP3LAME)
FIND_PACKAGE(Lame)
IF(LAME_FOUND)
SET(LMMS_HAVE_MP3LAME TRUE)
SET(STATUS_MP3LAME "OK")
ELSE(LAME_FOUND)
SET(STATUS_MP3LAME "not found, please install libmp3lame-dev (or similar)")
SET(LAME_LIBRARIES "")
SET(LAME_INCLUDE_DIRS "")
ENDIF(LAME_FOUND)
ELSE(WANT_MP3LAME)
SET(STATUS_MP3LAME "Disabled for build")
ENDIF(WANT_MP3LAME)
# check for OGG/Vorbis-libraries
IF(WANT_OGGVORBIS)
FIND_PACKAGE(OggVorbis)
@@ -593,6 +610,7 @@ MESSAGE(
"-----------------------------------------\n"
"* WAVE : OK\n"
"* OGG/VORBIS : ${STATUS_OGGVORBIS}\n"
"* MP3/Lame : ${STATUS_MP3LAME}\n"
)
MESSAGE(

View File

@@ -3,7 +3,7 @@
[![Build status](https://img.shields.io/travis/LMMS/lmms.svg?maxAge=3600)](https://travis-ci.org/LMMS/lmms)
[![Latest stable release](https://img.shields.io/github/release/LMMS/lmms.svg?maxAge=3600)](https://lmms.io/download)
[![Overall downloads on Github](https://img.shields.io/github/downloads/LMMS/lmms/total.svg?maxAge=3600)](https://github.com/LMMS/lmms/releases)
[![Join the chat at Discord](https://img.shields.io/badge/chat-on%20discord-7289DA.svg)](https://discord.gg/5kSc32Z)
[![Join the chat at Discord](https://img.shields.io/badge/chat-on%20discord-7289DA.svg)](https://discord.gg/3sc5su7)
[![Localise on transifex](https://img.shields.io/badge/localise-on_transifex-green.svg)](https://www.transifex.com/lmms/lmms/)
What is LMMS?

View File

@@ -0,0 +1,16 @@
# - Try to find LAME
# Once done this will define
#
# LAME_FOUND - system has liblame
# LAME_INCLUDE_DIRS - the liblame include directory
# LAME_LIBRARIES - The liblame libraries
find_path(LAME_INCLUDE_DIRS lame/lame.h)
find_library(LAME_LIBRARIES mp3lame)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Lame DEFAULT_MSG LAME_INCLUDE_DIRS LAME_LIBRARIES)
list(APPEND LAME_DEFINITIONS -DHAVE_LIBMP3LAME=1)
mark_as_advanced(LAME_INCLUDE_DIRS LAME_LIBRARIES LAME_DEFINITIONS)

View File

@@ -7,11 +7,17 @@ SET(CPACK_NSIS_URL_INFO_ABOUT "${PROJECT_URL}" PARENT_SCOPE)
SET(CPACK_NSIS_CONTACT "${PROJECT_EMAIL}" PARENT_SCOPE)
SET(CPACK_PACKAGE_EXECUTABLES "${CMAKE_PROJECT_NAME}.exe;${PROJECT_NAME_UCASE}" PARENT_SCOPE)
SET(CPACK_NSIS_MENU_LINKS "${CMAKE_PROJECT_NAME}.exe;${PROJECT_NAME_UCASE}" PARENT_SCOPE)
SET(CPACK_NSIS_DEFINES "!include ${CMAKE_SOURCE_DIR}/cmake/nsis/FileAssociation.nsh")
SET(CPACK_NSIS_DEFINES "
!include ${CMAKE_SOURCE_DIR}/cmake/nsis/FileAssociation.nsh
!include LogicLib.nsh
!include WinVer.nsh")
SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-win32")
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "
\\\${registerExtension} \\\"$INSTDIR\\\\${CMAKE_PROJECT_NAME}.exe\\\" \\\".mmp\\\" \\\"${PROJECT_NAME_UCASE} Project\\\"
\\\${registerExtension} \\\"$INSTDIR\\\\${CMAKE_PROJECT_NAME}.exe\\\" \\\".mmpz\\\" \\\"${PROJECT_NAME_UCASE} Project (compressed)\\\"
\\\${IfNot} \\\${AtMostWin7}
WriteRegDWORD HKLM \\\"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\SideBySide\\\" \\\"PreferExternalManifest\\\" \\\"1\\\"
\\\${EndIf}
" PARENT_SCOPE)
SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "
\\\${unregisterExtension} \\\".mmp\\\" \\\"${PROJECT_NAME_UCASE} Project\\\"
@@ -64,3 +70,4 @@ IF(LMMS_HAVE_STK)
INSTALL(FILES ${RAWWAVES} DESTINATION "${DATA_DIR}/stk/rawwaves")
ENDIF()
INSTALL(FILES "lmms.exe.manifest" DESTINATION .)

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<ms_windowsSettings:dpiAware xmlns:ms_windowsSettings="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</ms_windowsSettings:dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>

View File

@@ -31,7 +31,7 @@ FOREACH(_ts_file ${lmms_LOCALES})
COMMAND "${QT_LUPDATE_EXECUTABLE}" -locations none -no-obsolete -I ${CMAKE_SOURCE_DIR}/include/ ${LMMS_SRCS} ${LMMS_INCLUDES} ${LMMS_UIS} `find "\"${CMAKE_SOURCE_DIR}/plugins/\"" -type f -name '*.cpp' -or -name '*.h'` -ts "\"${_ts_file}\""
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
ADD_CUSTOM_TARGET(${_qm_target}
COMMAND "${QT_LRELEASE_EXECUTABLE}" "\"${_ts_file}\"" -qm "\"${_qm_file}\""
COMMAND "${QT_LRELEASE_EXECUTABLE}" "${_ts_file}" -qm "${_qm_file}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
LIST(APPEND ts_targets "${_ts_target}")
LIST(APPEND qm_targets "${_qm_target}")

View File

@@ -721,10 +721,6 @@ If you&apos;re interested in translating LMMS in another language or want to imp
<source>Input Gain:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>NOIS</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Input Noise:</source>
<translation type="unfinished"></translation>
@@ -741,10 +737,6 @@ If you&apos;re interested in translating LMMS in another language or want to imp
<source>Output Clip:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rate</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rate Enabled</source>
<translation type="unfinished"></translation>
@@ -753,10 +745,6 @@ If you&apos;re interested in translating LMMS in another language or want to imp
<source>Enable samplerate-crushing</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Depth</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Depth Enabled</source>
<translation type="unfinished"></translation>
@@ -769,20 +757,28 @@ If you&apos;re interested in translating LMMS in another language or want to imp
<source>Sample rate:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>STD</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Stereo difference:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Levels</source>
<source>Levels:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Levels:</source>
<source>NOISE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>FREQ</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>STEREO</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>QUANT</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2170,10 +2166,6 @@ Please make sure you have write permission to the file and the directory contain
<source>RATE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rate:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>AMNT</source>
<translation type="unfinished"></translation>
@@ -2194,6 +2186,10 @@ Please make sure you have write permission to the file and the directory contain
<source>Invert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Period:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FxLine</name>
@@ -3370,22 +3366,10 @@ You can remove and move FX channels in the context menu, which is accessed by ri
<source>FX channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>ENV/LFO</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>FUNC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>FX</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MIDI</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save preset</source>
<translation type="unfinished"></translation>
@@ -3394,10 +3378,6 @@ You can remove and move FX channels in the context menu, which is accessed by ri
<source>XML preset file (*.xpf)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>PLUGIN</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Pitch range (semitones)</source>
<translation type="unfinished"></translation>
@@ -3414,10 +3394,6 @@ You can remove and move FX channels in the context menu, which is accessed by ri
<source>Click here, if you want to save current instrument track settings in a preset file. Later you can load this preset by double-clicking it in the preset-browser.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MISC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Use these controls to view and edit the next/previous track in the song editor.</source>
<translation type="unfinished"></translation>
@@ -3426,6 +3402,30 @@ You can remove and move FX channels in the context menu, which is accessed by ri
<source>SAVE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Envelope, filter &amp; LFO</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Chord stacking &amp; arpeggio</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Effects</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MIDI settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Plugin</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Knob</name>
@@ -3913,14 +3913,6 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS.</source>
<source>Recover the file. Please don&apos;t run multiple instances of LMMS when you do this.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Ignore</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Launch LMMS as usual but with automatic backup disabled to prevent the present recover file from being overwritten.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Discard</source>
<translation type="unfinished"></translation>
@@ -3993,10 +3985,6 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS.</source>
<source>Recover session. Please save your work!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Automatic backup disabled. Remember to save your work!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Recovered project not saved</source>
<translation type="unfinished"></translation>
@@ -5706,14 +5694,6 @@ Reason: &quot;%2&quot;</source>
</context>
<context>
<name>ProjectNotes</name>
<message>
<source>Project notes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Put down your project notes here.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit Actions</source>
<translation type="unfinished"></translation>
@@ -5822,6 +5802,14 @@ Reason: &quot;%2&quot;</source>
<source>&amp;Color...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Project Notes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter project notes here</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ProjectRenderer</name>

View File

@@ -0,0 +1,89 @@
<?xml version="1.0"?>
<!DOCTYPE lmms-project>
<lmms-project version="1.0" creator="LMMS" creatorversion="1.2.0" type="song">
<head timesig_numerator="4" mastervol="100" timesig_denominator="4" bpm="140" masterpitch="0"/>
<song>
<trackcontainer width="600" x="5" y="5" maximized="0" height="300" visible="1" type="song" minimized="0">
<track muted="0" type="0" name="TripleOscillator" solo="0">
<instrumenttrack pan="0" fxch="0" usemasterpitch="1" pitchrange="1" pitch="0" basenote="57" vol="100">
<instrument name="tripleoscillator">
<tripleoscillator phoffset2="0" userwavefile0="" finer0="0" userwavefile1="" finer1="0" userwavefile2="" finer2="0" coarse0="0" coarse1="-12" coarse2="-24" finel0="0" finel1="0" modalgo1="2" modalgo2="2" finel2="0" pan0="0" modalgo3="2" pan1="0" stphdetun0="0" pan2="0" stphdetun1="0" wavetype0="0" stphdetun2="0" wavetype1="0" wavetype2="0" vol0="33" vol1="33" phoffset0="0" phoffset1="0" vol2="33"/>
</instrument>
<eldata fres="0.5" ftype="0" fcut="14000" fwet="0">
<elvol lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lspd_syncmode="0" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
<elcut lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lspd_syncmode="0" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
<elres lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lspd_syncmode="0" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
</eldata>
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
<arpeggiator arptime="100" arprange="1" arpskip="0" arptime_denominator="4" arptime_syncmode="0" arpmode="0" arpcycle="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpmiss="0" arpgate="100"/>
<midiport inputcontroller="0" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="0"/>
<fxchain numofeffects="0" enabled="0"/>
</instrumenttrack>
</track>
<track muted="0" type="2" name="Sample track" solo="0">
<sampletrack pan="0" vol="100">
<fxchain numofeffects="0" enabled="0"/>
</sampletrack>
</track>
<track muted="0" type="1" name="Beat/Bassline 0" solo="0">
<bbtrack>
<trackcontainer width="640" x="610" y="5" maximized="0" height="400" visible="0" type="bbtrackcontainer" minimized="0">
<track muted="0" type="0" name="Kicker" solo="0">
<instrumenttrack pan="0" fxch="0" usemasterpitch="1" pitchrange="1" pitch="0" basenote="57" vol="100">
<instrument name="kicker">
<kicker decay_numerator="4" decay_denominator="4" distend="0.8" click="0.4" endnote="0" version="1" decay_syncmode="0" decay="440" noise="0" slope="0.06" dist="0.8" env="0.163" startnote="1" startfreq="150" endfreq="40" gain="1"/>
</instrument>
<eldata fres="0.5" ftype="0" fcut="14000" fwet="0">
<elvol lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lspd_syncmode="0" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
<elcut lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lspd_syncmode="0" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
<elres lspd_denominator="4" sustain="0.5" pdel="0" userwavefile="" dec="0.5" lamt="0" latt="0" rel="0.1" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lspd_syncmode="0" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4"/>
</eldata>
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
<arpeggiator arptime="100" arprange="1" arpskip="0" arptime_denominator="4" arptime_syncmode="0" arpmode="0" arpcycle="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpmiss="0" arpgate="100"/>
<midiport inputcontroller="0" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="0"/>
<fxchain numofeffects="0" enabled="0"/>
</instrumenttrack>
<pattern steps="16" muted="0" type="0" name="Kicker" pos="0"/>
</track>
</trackcontainer>
</bbtrack>
</track>
<track muted="0" type="5" name="Automation track" solo="0">
<automationtrack/>
</track>
</trackcontainer>
<track muted="0" type="6" name="Automation track" solo="0">
<automationtrack/>
<automationpattern tens="1" mute="0" prog="0" name="Numerator" pos="0" len="192">
<object id="4975896"/>
</automationpattern>
<automationpattern tens="1" mute="0" prog="0" name="Denominator" pos="0" len="192">
<object id="6613237"/>
</automationpattern>
<automationpattern tens="1" mute="0" prog="0" name="Tempo" pos="0" len="192">
<object id="6054005"/>
</automationpattern>
<automationpattern tens="1" mute="0" prog="0" name="Master volume" pos="0" len="192">
<object id="1345820"/>
</automationpattern>
<automationpattern tens="1" mute="0" prog="0" name="Master pitch" pos="0" len="192">
<object id="5865711"/>
</automationpattern>
</track>
<fxmixer width="543" x="5" y="310" maximized="0" height="335" visible="1" minimized="0">
<fxchannel num="0" muted="0" volume="1" name="Master" soloed="0">
<fxchain numofeffects="0" enabled="0"/>
</fxchannel>
</fxmixer>
<ControllerRackView width="350" x="680" y="310" maximized="0" height="200" visible="1" minimized="0"/>
<pianoroll width="640" x="5" y="5" maximized="0" height="480" visible="0" minimized="0"/>
<automationeditor width="640" x="-36" y="0" maximized="0" height="400" visible="0" minimized="0"/>
<projectnotes width="640" x="700" y="10" maximized="0" height="400" visible="0" minimized="0"><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'Noto Sans'; font-size:9pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#e0e0e0;">Enter project notes here</span></p></body></html>]]></projectnotes>
<timeline lp1pos="192" lp0pos="0" lpstate="0"/>
<controllers/>
</song>
</lmms-project>

Binary file not shown.

Binary file not shown.

View File

@@ -139,6 +139,19 @@ PianoRoll {
qproperty-textShadow: rgb( 240, 240, 240 );
}
TabWidget {
background-color: #5b6571;
qproperty-tabText: rgba(255, 255, 255, 180);
qproperty-tabTitleText: #fff;
qproperty-tabSelected: #61666b;
qproperty-tabBackground: #3c434b;
qproperty-tabBorder: #3c434b;
}
GroupBox {
background-color: #5b6571;
}
/* main toolbar oscilloscope - can have transparent bg now */
VisualizationWidget {
@@ -281,6 +294,11 @@ TrackContainerView QFrame{
background-color: #49515b;
}
/* background for track controls */
TrackView > QWidget {
background-color: #5b6571;
}
/* autoscroll, loop, stop behaviour toggle buttons */
/* track background colors */
@@ -523,6 +541,12 @@ PluginDescWidget:hover {
background-color: #e0e0e0;
}
/* piano widget */
PianoView {
background-color: #14171a;
}
/* font sizes for text buttons */
FxMixerView QPushButton, EffectRackView QPushButton, ControllerRackView QPushButton {
@@ -543,6 +567,7 @@ FxLine {
/* persistent peak markers for fx peak meters */
Fader {
qproperty-peakGreen: rgb( 74, 253, 133);
qproperty-peakYellow: rgb(224, 222, 18);
qproperty-peakRed: rgb( 255, 100, 100);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

View File

@@ -136,6 +136,19 @@ PianoRoll {
qproperty-textShadow: #fff;
}
TabWidget {
background-color: #262b30;
qproperty-tabText: rgba(255, 255, 255, 180);
qproperty-tabTitleText: #fff;
qproperty-tabSelected: #323940;
qproperty-tabBackground: #181b1f;
qproperty-tabBorder: #181b1f;
}
GroupBox {
background-color: #262b30;
}
/* main toolbar oscilloscope - can have transparent bg now */
VisualizationWidget {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

View File

@@ -85,3 +85,7 @@ Chrissy McManus
Oskar Wallgren
<oskar/dot/wallgren13/at/gmail/dot/com>
Development
Michael Gregorius
<michael/dot/gregorius/dot/git/at/arcor/dot/de>
Development

View File

@@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH LMMS 1 "February 17, 2016"
.TH LMMS 1 "June 15, 2017"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@@ -52,6 +52,9 @@ lmms \- software for easy music production
.RB "[ \--\fBloop\fP ]"
.br
.B lmms
.RB "[ \--\fBmode\fP \fIstereomode\fP ]"
.br
.B lmms
.RB "[ \--\fBoutput\fP \fIpath\fP ]"
.br
.B lmms
@@ -94,7 +97,7 @@ Get the configuration from \fIconfigfile\fP instead of ~/.lmmsrc.xml (default)
.IP "\fB\-d, --dump\fP \fIin\fP
Dump XML of compressed file \fIin\fP (i.e. MMPZ-file)
.IP "\fB\-f, --format\fP \fIformat\fP
Specify format of render-output where \fIformat\fP is either 'wav' or 'ogg'
Specify format of render-output where \fIformat\fP is either 'wav', 'ogg' or 'mp3'.
.IP "\fB\ --geometry\fP \fIgeometry\fP
Specify the prefered size and position of the main window
.br
@@ -111,6 +114,8 @@ Import MIDI file \fIin\fP
If -e is specified lmms exits after importing the file.
.IP "\fB\-l, --loop
Render the given file as a loop, i.e. stop rendering at exactly the end of the song. Additional silence or reverb tails at the end of the song are not rendered.
.IP "\fB\-m, --mode\fP \fIstereomode\fP
Set the stereo mode used for the MP3 export. \fIstereomode\fP can be either 's' (stereo mode), 'j' (joint stereo) or 'm' (mono). If no mode is given 'j' is used as the default.
.IP "\fB\-o, --output\fP \fIpath\fP
Render into \fIpath\fP
.br

74
include/AudioFileMP3.h Normal file
View File

@@ -0,0 +1,74 @@
/*
* AudioFileMP3.h - Audio-device which encodes a wave stream into
* an MP3 file. This is used for song export.
*
* Copyright (c) 2017 to present Michael Gregorius <michael.gregorius.git/at/arcor[dot]de>
*
* This file is part of LMMS - https://lmms.io
*
* 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 AUDIO_FILE_MP3_H
#define AUDIO_FILE_MP3_H
#include "lmmsconfig.h"
#ifdef LMMS_HAVE_MP3LAME
#include "AudioFileDevice.h"
#include "lame/lame.h"
class AudioFileMP3 : public AudioFileDevice
{
public:
AudioFileMP3( OutputSettings const & outputSettings,
const ch_cnt_t _channels,
bool & successful,
const QString & _file,
Mixer* mixer );
virtual ~AudioFileMP3();
static AudioFileDevice * getInst( const QString & outputFilename,
OutputSettings const & outputSettings,
const ch_cnt_t channels,
Mixer* mixer,
bool & successful )
{
return new AudioFileMP3( outputSettings, channels, successful,
outputFilename, mixer );
}
protected:
virtual void writeBuffer( const surroundSampleFrame * /* _buf*/,
const fpp_t /*_frames*/,
const float /*_master_gain*/ );
private:
void flushRemainingBuffers();
bool initEncoder();
void tearDownEncoder();
private:
lame_t m_lame;
};
#endif
#endif

View File

@@ -407,7 +407,7 @@ public:
{
}
float getRoundedValue() const;
float getDigitCount();
int getDigitCount() const;
defaultTypedMethods(float);
} ;

View File

@@ -217,6 +217,9 @@ public:
const QString & value( const QString & cls,
const QString & attribute ) const;
const QString & value( const QString & cls,
const QString & attribute,
const QString & defaultVal ) const;
void setValue( const QString & cls, const QString & attribute,
const QString & value );
void deleteValue( const QString & cls, const QString & attribute);

View File

@@ -57,7 +57,7 @@ public:
protected:
virtual void mousePressEvent( QMouseEvent * _me );
virtual void resizeEvent( QResizeEvent * _re );
virtual void paintEvent( QPaintEvent * _pe );
private:

View File

@@ -110,8 +110,7 @@ public:
enum SessionState
{
Normal,
Recover,
Limited,
Recover
};
void setSession( SessionState session )
@@ -143,7 +142,7 @@ public:
return m_keyMods.m_alt;
}
static void saveWidgetState( QWidget * _w, QDomElement & _de, QSize const & sizeIfInvisible = QSize(0, 0) );
static void saveWidgetState( QWidget * _w, QDomElement & _de );
static void restoreWidgetState( QWidget * _w, const QDomElement & _de );
public slots:

View File

@@ -38,6 +38,13 @@ public:
NumDepths
};
enum StereoMode
{
StereoMode_Stereo,
StereoMode_JointStereo,
StereoMode_Mono
};
class BitRateSettings
{
public:
@@ -60,10 +67,19 @@ public:
public:
OutputSettings( sample_rate_t sampleRate,
BitRateSettings const & bitRateSettings,
BitDepth bitDepth ) :
BitDepth bitDepth,
StereoMode stereoMode ) :
m_sampleRate(sampleRate),
m_bitRateSettings(bitRateSettings),
m_bitDepth(bitDepth)
m_bitDepth(bitDepth),
m_stereoMode(stereoMode)
{
}
OutputSettings( sample_rate_t sampleRate,
BitRateSettings const & bitRateSettings,
BitDepth bitDepth ) :
OutputSettings(sampleRate, bitRateSettings, bitDepth, StereoMode_Stereo )
{
}
@@ -76,10 +92,14 @@ public:
BitDepth getBitDepth() const { return m_bitDepth; }
void setBitDepth(BitDepth bitDepth) { m_bitDepth = bitDepth; }
StereoMode getStereoMode() const { return m_stereoMode; }
void setStereoMode(StereoMode stereoMode) { m_stereoMode = stereoMode; }
private:
sample_rate_t m_sampleRate;
BitRateSettings m_bitRateSettings;
BitDepth m_bitDepth;
StereoMode m_stereoMode;
};
#endif

View File

@@ -88,7 +88,7 @@ public:
{
return m_patternType;
}
void checkType();
// next/previous track based on position in the containing track
Pattern * previousPattern() const;
@@ -132,6 +132,7 @@ private:
MidiTime beatPatternLength() const;
void setType( PatternTypes _new_pattern_type );
void checkType();
void resizeToFirstTrack();

View File

@@ -39,11 +39,14 @@ public:
{
WaveFile,
OggFile,
MP3File,
NumFileFormats
} ;
struct FileEncodeDevice
{
bool isAvailable() const { return m_getDevInst != nullptr; }
ExportFileFormats m_fileFormat;
const char * m_description;
const char * m_extension;

View File

@@ -153,6 +153,7 @@ public:
public slots:
void updateTcos();
void setPlayingTcos( bool isPlaying );
private:
FloatModel m_volumeModel;

View File

@@ -97,6 +97,10 @@ public:
void processNextBuffer();
inline int getLoadingTrackCount() const
{
return m_nLoadingTrack;
}
inline int getMilliseconds() const
{
return m_elapsedMilliSeconds;
@@ -339,6 +343,7 @@ private:
ControllerVector m_controllers;
int m_nLoadingTrack;
QString m_fileName;
QString m_oldFileName;

View File

@@ -81,6 +81,7 @@ public slots:
void setEditModeSelect();
void updatePosition( const MidiTime & t );
void updatePositionLine();
protected:
virtual void closeEvent( QCloseEvent * ce );
@@ -152,6 +153,9 @@ public:
SongEditor* m_editor;
protected:
virtual void resizeEvent( QResizeEvent * event );
protected slots:
void play();
void record();
@@ -162,6 +166,7 @@ protected slots:
signals:
void playTriggered();
void resized();
private:
QAction* m_addBBTrackAction;

View File

@@ -29,25 +29,47 @@
#include <QWidget>
#include <QtCore/QMap>
const int TEXT_TAB_HEIGHT = 14;
const int GRAPHIC_TAB_HEIGHT = 17;
class TabWidget : public QWidget
{
Q_OBJECT
public:
TabWidget( const QString & _caption, QWidget * _parent );
TabWidget( const QString & _caption, QWidget * _parent, bool usePixmap = false );
virtual ~TabWidget();
void addTab( QWidget * _w, const QString & _name, int _idx = -1 );
void addTab( QWidget * w, const QString & name, const char *pixmap = NULL, int idx = -1 );
void setActiveTab( int _idx );
void setActiveTab( int idx );
int findTabAtPos( const QPoint *pos );
inline int activeTab() const
{
return( m_activeTab );
}
// Themeability
Q_PROPERTY( QColor tabText READ tabText WRITE setTabText)
Q_PROPERTY( QColor tabTitleText READ tabTitleText WRITE setTabTitleText)
Q_PROPERTY( QColor tabSelected READ tabSelected WRITE setTabSelected)
Q_PROPERTY( QColor tabBackground READ tabBackground WRITE setTabBackground)
Q_PROPERTY( QColor tabBorder READ tabBorder WRITE setTabBorder)
QColor tabText() const;
void setTabText( const QColor & c );
QColor tabTitleText() const;
void setTabTitleText( const QColor & c );
QColor tabSelected() const;
void setTabSelected( const QColor & c );
QColor tabBackground() const;
void setTabBackground( const QColor & c );
QColor tabBorder() const;
void setTabBorder( const QColor & c );
protected:
virtual bool event( QEvent * event );
virtual void mousePressEvent( QMouseEvent * _me );
virtual void paintEvent( QPaintEvent * _pe );
virtual void resizeEvent( QResizeEvent * _re );
@@ -57,16 +79,26 @@ protected:
private:
struct widgetDesc
{
QWidget * w; // ptr to widget
QString name; // name for widget
int nwidth; // width of name when painting
QWidget * w; // ptr to widget
const char * pixmap; // artwork for the widget
QString name; // name for widget
int nwidth; // width of name when painting (only valid for text tab)
} ;
typedef QMap<int, widgetDesc> widgetStack;
widgetStack m_widgets;
int m_activeTab;
QString m_caption;
quint8 m_tabheight;
int m_activeTab;
QString m_caption; // Tab caption, used as the tooltip text on icon tabs
quint8 m_tabbarHeight; // The height of the tab bar
quint8 m_tabheight; // The height of the tabs
bool m_usePixmap; // true if the tabs are to be displayed with icons. False for text tabs.
QColor m_tabText; // The color of the tabs' text.
QColor m_tabTitleText; // The color of the TabWidget's title text.
QColor m_tabSelected; // The highlighting color for the selected tab.
QColor m_tabBackground; // The TabWidget's background color.
QColor m_tabBorder; // The TabWidget's borders color.
} ;
#endif

View File

@@ -29,9 +29,10 @@
#include <QToolButton>
#include <QLineEdit>
class TrackView;
class TrackRenameLineEdit;
class TrackLabelButton : public QToolButton
{
@@ -60,7 +61,7 @@ protected:
private:
TrackView * m_trackView;
QString m_iconName;
QLineEdit * m_renameLineEdit;
TrackRenameLineEdit * m_renameLineEdit;
QRect m_buttonRect;
QString elideName( const QString &name );

View File

@@ -0,0 +1,46 @@
/*
* TrackRenameLineEdit.h - class TrackRenameLineEdit
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2017 Alexandre Almeida <http://m374lx.users.sourceforge.net/>
*
* This file is part of LMMS - https://lmms.io
*
* 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 TRACK_RENAME_LINE_EDIT_H
#define TRACK_RENAME_LINE_EDIT_H
#include <QLineEdit>
class TrackRenameLineEdit : public QLineEdit
{
Q_OBJECT
public:
TrackRenameLineEdit( QWidget * parent );
void show();
protected:
virtual void keyPressEvent( QKeyEvent * ke );
private:
QString m_oldName;
} ;
#endif

36
plugins/Bitcrush/BitcrushControlDialog.cpp Normal file → Executable file
View File

@@ -41,73 +41,73 @@ BitcrushControlDialog::BitcrushControlDialog( BitcrushControls * controls ) :
QPalette pal;
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
setPalette( pal );
setFixedSize( 215, 120 );
setFixedSize( 181, 128 );
// labels
QLabel * inLabel = new QLabel( tr( "IN" ), this );
inLabel->move( 12, 10);
inLabel->move( 24, 15 );
QLabel * outLabel = new QLabel( tr( "OUT" ), this );
outLabel->move( 176, 10 );
outLabel->move( 139, 15 );
// input knobs
Knob * inGain = new Knob( knobBright_26, this );
inGain->move( 12, 25 );
inGain->move( 16, 32 );
inGain->setModel( & controls->m_inGain );
inGain->setLabel( tr( "GAIN" ) );
inGain->setHintText( tr( "Input Gain:" ) + " ", " dBFS" );
Knob * inNoise = new Knob( knobBright_26, this );
inNoise->move( 12, 70 );
inNoise->move( 14, 76 );
inNoise->setModel( & controls->m_inNoise );
inNoise->setLabel( tr( "NOIS" ) );
inNoise->setLabel( tr( "NOISE" ) );
inNoise->setHintText( tr( "Input Noise:" ) + " ", "%" );
// output knobs
Knob * outGain = new Knob( knobBright_26, this );
outGain->move( 176, 25 );
outGain->move( 138, 32 );
outGain->setModel( & controls->m_outGain );
outGain->setLabel( tr( "GAIN" ) );
outGain->setHintText( tr( "Output Gain:" ) + " ", " dBFS" );
Knob * outClip = new Knob( knobBright_26, this );
outClip->move( 176, 70 );
outClip->move( 138, 76 );
outClip->setModel( & controls->m_outClip );
outClip->setLabel( tr( "CLIP" ) );
outClip->setHintText( tr( "Output Clip:" ) + " ", "%" );
// leds
LedCheckBox * rateEnabled = new LedCheckBox( tr( "Rate" ), this, tr( "Rate Enabled" ), LedCheckBox::Green );
rateEnabled->move( 50, 30 );
LedCheckBox * rateEnabled = new LedCheckBox( "", this, tr( "Rate Enabled" ), LedCheckBox::Green );
rateEnabled->move( 64, 14 );
rateEnabled->setModel( & controls->m_rateEnabled );
ToolTip::add( rateEnabled, tr( "Enable samplerate-crushing" ) );
LedCheckBox * depthEnabled = new LedCheckBox( tr( "Depth" ), this, tr( "Depth Enabled" ), LedCheckBox::Green );
depthEnabled->move( 50, 80 );
LedCheckBox * depthEnabled = new LedCheckBox( "", this, tr( "Depth Enabled" ), LedCheckBox::Green );
depthEnabled->move( 101, 14 );
depthEnabled->setModel( & controls->m_depthEnabled );
ToolTip::add( depthEnabled, tr( "Enable bitdepth-crushing" ) );
// rate crushing knobs
Knob * rate = new Knob( knobBright_26, this );
rate->move( 100, 20 );
rate->move( 59, 32 );
rate->setModel( & controls->m_rate );
rate->setLabel( tr( "Rate" ) );
rate->setLabel( tr( "FREQ" ) );
rate->setHintText( tr( "Sample rate:" ) + " ", " Hz" );
Knob * stereoDiff = new Knob( knobBright_26, this );
stereoDiff->move( 140, 20 );
stereoDiff->move( 72, 76 );
stereoDiff->setModel( & controls->m_stereoDiff );
stereoDiff->setLabel( tr( "STD" ) );
stereoDiff->setLabel( tr( "STEREO" ) );
stereoDiff->setHintText( tr( "Stereo difference:" ) + " ", "%" );
// depth crushing knob
Knob * levels = new Knob( knobBright_26, this );
levels->move( 140, 70 );
levels->move( 92, 32 );
levels->setModel( & controls->m_levels );
levels->setLabel( tr( "Levels" ) );
levels->setLabel( tr( "QUANT" ) );
levels->setHintText( tr( "Levels:" ) + " ", "" );
}

BIN
plugins/Bitcrush/artwork.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -32,7 +32,7 @@
DelayControls::DelayControls( DelayEffect* effect ):
EffectControls( effect ),
m_effect ( effect ),
m_delayTimeModel( 0.5, 0.01, 5.0, 0.0001, 20000.0, this, tr( "Delay Samples" )) ,
m_delayTimeModel( 0.5, 0.01, 5.0, 0.0001, 5000.0, this, tr( "Delay Samples" )) ,
m_feedbackModel(0.0f,0.0f,1.0f,0.01f,this,tr( "Feedback" ) ),
m_lfoTimeModel(2.0, 0.01, 5.0, 0.0001, 20000.0, this, tr( "Lfo Frequency" ) ),
m_lfoAmountModel(0.0, 0.0, 0.5, 0.0001, 2000.0, this, tr ( "Lfo Amount" ) ),

View File

@@ -36,7 +36,7 @@ StereoDelay::StereoDelay( int maxTime, int sampleRate )
m_maxLength = maxTime * sampleRate;
m_length = m_maxLength;
m_index = 0;
m_writeIndex = 0;
m_feedback = 0.0f;
setSampleRate( sampleRate );
}
@@ -57,13 +57,13 @@ StereoDelay::~StereoDelay()
void StereoDelay::tick( sampleFrame frame )
{
m_index = ( int )m_length > 0
? ( m_index + 1 ) % ( int ) m_length
: m_index;
float lOut = m_buffer[ m_index ][ 0 ];
float rOut = m_buffer[ m_index ] [1 ];
m_buffer[ m_index ][ 0 ] = frame[ 0 ] + ( lOut * m_feedback );
m_buffer[ m_index ][ 1 ] = frame[ 1 ] + ( rOut * m_feedback );
m_writeIndex = ( m_writeIndex + 1 ) % ( int )m_maxLength;
int readIndex = m_writeIndex - m_length;
if (readIndex < 0 ) { readIndex += m_maxLength; }
float lOut = m_buffer[ readIndex ][ 0 ];
float rOut = m_buffer[ readIndex ] [1 ];
m_buffer[ m_writeIndex ][ 0 ] = frame[ 0 ] + ( lOut * m_feedback );
m_buffer[ m_writeIndex ][ 1 ] = frame[ 1 ] + ( rOut * m_feedback );
frame[ 0 ] = lOut;
frame[ 1 ] = rOut;
}
@@ -71,6 +71,8 @@ void StereoDelay::tick( sampleFrame frame )
void StereoDelay::setSampleRate( int sampleRate )
{
if( m_buffer )

View File

@@ -52,7 +52,7 @@ private:
sampleFrame* m_buffer;
int m_maxLength;
float m_length;
int m_index;
int m_writeIndex;
float m_feedback;
float m_maxTime;
};

24
plugins/DualFilter/DualFilterControlDialog.cpp Normal file → Executable file
View File

@@ -49,15 +49,15 @@ DualFilterControlDialog::DualFilterControlDialog( DualFilterControls* controls )
QPalette pal;
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
setPalette( pal );
setFixedSize( 150, 220 );
setFixedSize( 373, 109 );
makeknob( cut1Knob, 33, 30, m_cut1Model, tr( "FREQ" ), tr( "Cutoff frequency" ), "Hz" )
makeknob( res1Knob, 75, 30, m_res1Model, tr( "RESO" ), tr( "Resonance" ), "" )
makeknob( gain1Knob, 117, 30, m_gain1Model, tr( "GAIN" ), tr( "Gain" ), "%" )
makeknob( mixKnob, 62, 100, m_mixModel, tr( "MIX" ), tr( "Mix" ), "" )
makeknob( cut2Knob, 33, 145, m_cut2Model, tr( "FREQ" ), tr( "Cutoff frequency" ), "Hz" )
makeknob( res2Knob, 75, 145, m_res2Model, tr( "RESO" ), tr( "Resonance" ), "" )
makeknob( gain2Knob, 117, 145, m_gain2Model, tr( "GAIN" ), tr( "Gain" ), "%" )
makeknob( cut1Knob, 24, 26, m_cut1Model, tr( "FREQ" ), tr( "Cutoff frequency" ), "Hz" )
makeknob( res1Knob, 74, 26, m_res1Model, tr( "RESO" ), tr( "Resonance" ), "" )
makeknob( gain1Knob, 124, 26, m_gain1Model, tr( "GAIN" ), tr( "Gain" ), "%" )
makeknob( mixKnob, 173, 37, m_mixModel, tr( "MIX" ), tr( "Mix" ), "" )
makeknob( cut2Knob, 222, 26, m_cut2Model, tr( "FREQ" ), tr( "Cutoff frequency" ), "Hz" )
makeknob( res2Knob, 272, 26, m_res2Model, tr( "RESO" ), tr( "Resonance" ), "" )
makeknob( gain2Knob, 322, 26, m_gain2Model, tr( "GAIN" ), tr( "Gain" ), "%" )
gain1Knob-> setVolumeKnob( true );
gain2Knob-> setVolumeKnob( true );
@@ -67,20 +67,20 @@ DualFilterControlDialog::DualFilterControlDialog( DualFilterControls* controls )
LedCheckBox * enabled2Toggle = new LedCheckBox( "", this,
tr( "Filter 2 enabled" ), LedCheckBox::Green );
enabled1Toggle -> move( 5, 30 );
enabled1Toggle -> move( 12, 11 );
enabled1Toggle -> setModel( &controls -> m_enabled1Model );
ToolTip::add( enabled1Toggle, tr( "Click to enable/disable Filter 1" ) );
enabled2Toggle -> move( 5, 145 );
enabled2Toggle -> move( 210, 11 );
enabled2Toggle -> setModel( &controls -> m_enabled2Model );
ToolTip::add( enabled2Toggle, tr( "Click to enable/disable Filter 2" ) );
ComboBox * m_filter1ComboBox = new ComboBox( this );
m_filter1ComboBox->setGeometry( 5, 70, 140, 22 );
m_filter1ComboBox->setGeometry( 19, 70, 137, 22 );
m_filter1ComboBox->setFont( pointSize<8>( m_filter1ComboBox->font() ) );
m_filter1ComboBox->setModel( &controls->m_filter1Model );
ComboBox * m_filter2ComboBox = new ComboBox( this );
m_filter2ComboBox->setGeometry( 5, 185, 140, 22 );
m_filter2ComboBox->setGeometry( 217, 70, 137, 22 );
m_filter2ComboBox->setFont( pointSize<8>( m_filter2ComboBox->font() ) );
m_filter2ComboBox->setModel( &controls->m_filter2Model );
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 934 B

View File

@@ -70,6 +70,10 @@ EqEffect::~EqEffect()
bool EqEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames )
{
//wet/dry controls
const float dry = dryLevel();
const float wet = wetLevel();
sample_t dryS[2];
// setup sample exact controls
float hpRes = m_eqControls.m_hpResModel.value();
float lowShelfRes = m_eqControls.m_lowShelfResModel.value();
@@ -205,6 +209,9 @@ bool EqEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames )
for( fpp_t f = 0; f < frames; f++)
{
//wet dry buffer
dryS[0] = buf[f][0];
dryS[1] = buf[f][1];
if( hpActive )
{
m_hp12.setParameters( sampleRate, *hpFreqPtr, *hpResPtr, 1 );
@@ -296,6 +303,10 @@ bool EqEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames )
}
}
//apply wet / dry levels
buf[f][1] = ( dry * dryS[1] ) + ( wet * buf[f][1] );
buf[f][0] = ( dry * dryS[0] ) + ( wet * buf[f][0] );
//increment pointers if needed
hpResPtr += hpResInc;
lowShelfResPtr += lowShelfResInc;

View File

@@ -35,7 +35,7 @@ FlangerControls::FlangerControls( FlangerEffect *effect ) :
EffectControls ( effect ),
m_effect ( effect ),
m_delayTimeModel(0.001, 0.0001, 0.050, 0.0001, this, tr( "Delay Samples" ) ) ,
m_lfoFrequencyModel( 0.25, 0.01, 5, 0.0001, 20000.0 ,this, tr( "Lfo Frequency" ) ),
m_lfoFrequencyModel( 0.25, 0.01, 60, 0.0001, 60000.0 ,this, tr( "Lfo Frequency" ) ),
m_lfoAmountModel( 0.0, 0.0, 0.0025 , 0.0001 , this , tr( "Seconds" ) ),
m_feedbackModel( 0.0 , 0.0 , 1.0 , 0.0001, this, tr( "Regen" ) ),
m_whiteNoiseAmountModel( 0.0 , 0.0 , 0.05 , 0.0001, this, tr( "Noise" ) ),

View File

@@ -52,7 +52,7 @@ FlangerControlsDialog::FlangerControlsDialog( FlangerControls *controls ) :
lfoFreqKnob->setVolumeKnob( false );
lfoFreqKnob->setModel( &controls->m_lfoFrequencyModel );
lfoFreqKnob->setLabel( tr( "RATE" ) );
lfoFreqKnob->setHintText( tr ( "Rate:" ) , "Hz" );
lfoFreqKnob->setHintText( tr ( "Period:" ) , " Sec" );
Knob * lfoAmtKnob = new Knob( knobBright_26, this );
lfoAmtKnob->move( 85,10 );

View File

@@ -94,7 +94,7 @@ bool FlangerEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames )
const float noise = m_flangerControls.m_whiteNoiseAmountModel.value();
float amplitude = m_flangerControls.m_lfoAmountModel.value() * Engine::mixer()->processingSampleRate();
bool invertFeedback = m_flangerControls.m_invertFeedbackModel.value();
m_lfo->setFrequency( m_flangerControls.m_lfoFrequencyModel.value() );
m_lfo->setFrequency( 1.0/m_flangerControls.m_lfoFrequencyModel.value() );
m_lDelay->setFeedback( m_flangerControls.m_feedbackModel.value() );
m_rDelay->setFeedback( m_flangerControls.m_feedbackModel.value() );
sample_t dryS[2];
@@ -107,8 +107,8 @@ bool FlangerEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames )
dryS[0] = buf[f][0];
dryS[1] = buf[f][1];
m_lfo->tick(&leftLfo, &rightLfo);
m_lDelay->setLength( ( float )length + ( amplitude * leftLfo ) );
m_rDelay->setLength( ( float )length+ ( amplitude * rightLfo ) );
m_lDelay->setLength( ( float )length + amplitude * (leftLfo+1.0) );
m_rDelay->setLength( ( float )length + amplitude * (rightLfo+1.0) );
if(invertFeedback)
{
m_lDelay->tick( &buf[f][1] );

View File

@@ -34,7 +34,7 @@ MonoDelay::MonoDelay( int maxTime , int sampleRate )
m_maxLength = maxTime * sampleRate;
m_length = m_maxLength;
m_index = 0;
m_writeIndex = 0;
m_feedback = 0.0f;
setSampleRate( sampleRate );
}
@@ -54,11 +54,11 @@ MonoDelay::~MonoDelay()
void MonoDelay::tick( sample_t* sample )
{
m_index = ( int )m_length > 0
? ( m_index + 1 ) % ( int )m_length
: m_index;
float out = m_buffer[ m_index ];
m_buffer[ m_index ] = *sample + ( out * m_feedback );
m_writeIndex = ( m_writeIndex + 1 ) % ( int )m_maxLength;
int readIndex = m_writeIndex - m_length;
if (readIndex < 0 ) { readIndex += m_maxLength; }
float out = m_buffer[ readIndex ];
m_buffer[ m_writeIndex ] = *sample + ( out * m_feedback );
*sample = out;
}

View File

@@ -52,7 +52,7 @@ private:
sample_t* m_buffer;
int m_maxLength;
float m_length;
int m_index;
int m_writeIndex;
float m_feedback;
float m_maxTime;
};

View File

@@ -2,6 +2,11 @@ if(LMMS_HAVE_GIG)
INCLUDE(BuildPlugin)
INCLUDE_DIRECTORIES(${GIG_INCLUDE_DIRS})
# Disable C++11 on Clang until gig.h is patched
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
REMOVE_DEFINITIONS(-std=c++0x)
ENDIF()
# Required for not crashing loading files with libgig
SET(GCC_COVERAGE_COMPILE_FLAGS "-fexceptions")
add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})

View File

@@ -1066,7 +1066,6 @@ void GigInstrumentView::showFileDialog()
types << tr( "GIG Files (*.gig)" );
ofd.setNameFilters( types );
QString dir;
if( k->m_filename != "" )
{
QString f = SampleBuffer::tryToMakeAbsolute( k->m_filename );

View File

@@ -30,7 +30,6 @@
#include "LcdSpinBox.h"
#include "GigPlayer.h"
#include <fluidsynth.h>
#include <QWidget>
#include <QLabel>

View File

@@ -7,18 +7,18 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
BUILD_PLUGIN(
reverbsc
ReverbSC.cpp
ReverbSCControls.cpp
ReverbSCControlDialog.cpp
ReverbSC.cpp
ReverbSCControls.cpp
ReverbSCControlDialog.cpp
base.c
revsc.c
dcblock.c
MOCFILES
ReverbSC.h
ReverbSCControls.h
ReverbSCControlDialog.h
base.h
revsc.h
dcblock.h
dcblock.c
ReverbSC.h
MOCFILES
ReverbSCControls.h
ReverbSCControlDialog.h
EMBEDDED_RESOURCES artwork.png logo.png
)

View File

@@ -58,8 +58,8 @@ ReverbSCEffect::ReverbSCEffect( Model* parent, const Descriptor::SubPluginFeatur
sp_dcblock_create(&dcblk[0]);
sp_dcblock_create(&dcblk[1]);
sp_dcblock_init(sp, dcblk[0]);
sp_dcblock_init(sp, dcblk[1]);
sp_dcblock_init(sp, dcblk[0], Engine::mixer()->currentQualitySettings().sampleRateMultiplier() );
sp_dcblock_init(sp, dcblk[1], Engine::mixer()->currentQualitySettings().sampleRateMultiplier() );
}
ReverbSCEffect::~ReverbSCEffect()
@@ -125,6 +125,27 @@ bool ReverbSCEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
return isRunning();
}
void ReverbSCEffect::changeSampleRate()
{
// Change sr variable in Soundpipe. does not need to be destroyed
sp->sr = Engine::mixer()->processingSampleRate();
mutex.lock();
sp_revsc_destroy(&revsc);
sp_dcblock_destroy(&dcblk[0]);
sp_dcblock_destroy(&dcblk[1]);
sp_revsc_create(&revsc);
sp_revsc_init(sp, revsc);
sp_dcblock_create(&dcblk[0]);
sp_dcblock_create(&dcblk[1]);
sp_dcblock_init(sp, dcblk[0], Engine::mixer()->currentQualitySettings().sampleRateMultiplier() );
sp_dcblock_init(sp, dcblk[1], Engine::mixer()->currentQualitySettings().sampleRateMultiplier() );
mutex.unlock();
}
extern "C"
{

View File

@@ -48,12 +48,14 @@ public:
return &m_reverbSCControls;
}
void changeSampleRate();
private:
ReverbSCControls m_reverbSCControls;
sp_data *sp;
sp_revsc *revsc;
sp_dcblock *dcblk[2];
QMutex mutex;
friend class ReverbSCControls;
} ;

View File

@@ -38,6 +38,7 @@ ReverbSCControls::ReverbSCControls( ReverbSCEffect* effect ) :
m_colorModel( 10000.0f, 100.0f, 15000.0f, 0.1f, this, tr( "Color" ) ),
m_outputGainModel( 0.0f, -60.0f, 15, 0.1f, this, tr( "Output Gain" ) )
{
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( changeSampleRate() ));
}
void ReverbSCControls::changeControl()
@@ -60,3 +61,7 @@ void ReverbSCControls::saveSettings( QDomDocument& doc, QDomElement& _this )
m_outputGainModel.saveSettings( doc, _this, "output_gain" );
}
void ReverbSCControls::changeSampleRate()
{
m_effect->changeSampleRate();
}

View File

@@ -61,6 +61,7 @@ public:
private slots:
void changeControl();
void changeSampleRate();
private:
ReverbSCEffect* m_effect;

View File

@@ -25,7 +25,7 @@ typedef struct sp_auxdata {
typedef struct sp_data {
SPFLOAT *out;
int sr;
uint32_t sr;
int nchan;
unsigned long len;
unsigned long pos;

View File

@@ -10,6 +10,7 @@
*
*/
#include <math.h>
#include <stdlib.h>
#include "base.h"
#include "dcblock.h"
@@ -26,11 +27,11 @@ int sp_dcblock_destroy(sp_dcblock **p)
return SP_OK;
}
int sp_dcblock_init(sp_data *sp, sp_dcblock *p)
int sp_dcblock_init(sp_data *sp, sp_dcblock *p, int oversampling )
{
p->outputs = 0.0;
p->inputs = 0.0;
p->gain = 0.99;
p->gain = pow( 0.99, 1.0f / oversampling );
if (p->gain == 0.0 || p->gain>=1.0 || p->gain<=-1.0)
p->gain = 0.99;
return SP_OK;

View File

@@ -7,5 +7,5 @@ typedef struct {
int sp_dcblock_create(sp_dcblock **p);
int sp_dcblock_destroy(sp_dcblock **p);
int sp_dcblock_init(sp_data *sp, sp_dcblock *p);
int sp_dcblock_init(sp_data *sp, sp_dcblock *p, int oversampling );
int sp_dcblock_compute(sp_data *sp, sp_dcblock *p, SPFLOAT *in, SPFLOAT *out);

View File

@@ -87,10 +87,10 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
m_managePluginButton = new PixmapButton( this, "" );
m_managePluginButton->setCheckable( false );
m_managePluginButton->setCursor( Qt::PointingHandCursor );
m_managePluginButton->setActiveGraphic( embed::getIconPixmap(
"track_op_menu_active" ) );
m_managePluginButton->setInactiveGraphic( embed::getIconPixmap(
"track_op_menu" ) );
m_managePluginButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
"controls_active" ) );
m_managePluginButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
"controls" ) );
connect( m_managePluginButton, SIGNAL( clicked() ), _ctl,
SLOT( managePlugin() ) );
ToolTip::add( m_managePluginButton, tr( "Control VST-plugin from LMMS host" ) );
@@ -98,8 +98,8 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
m_managePluginButton->setWhatsThis(
tr( "Click here, if you want to control VST-plugin from host." ) );
m_managePluginButton->setMinimumWidth( 21 );
m_managePluginButton->setMaximumWidth( 21 );
m_managePluginButton->setMinimumWidth( 26 );
m_managePluginButton->setMaximumWidth( 26 );
m_managePluginButton->setMinimumHeight( 21 );
m_managePluginButton->setMaximumHeight( 21 );

View File

Before

Width:  |  Height:  |  Size: 841 B

After

Width:  |  Height:  |  Size: 841 B

View File

Before

Width:  |  Height:  |  Size: 824 B

After

Width:  |  Height:  |  Size: 824 B

View File

@@ -1081,7 +1081,6 @@ void sf2InstrumentView::showFileDialog()
types << tr( "SoundFont2 Files (*.sf2)" );
ofd.setNameFilters( types );
QString dir;
if( k->m_filename != "" )
{
QString f = SampleBuffer::tryToMakeAbsolute( k->m_filename );

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

View File

@@ -42,6 +42,7 @@
#include "Mixer.h"
#include "GuiApplication.h"
#include "PixmapButton.h"
#include "SampleBuffer.h"
#include "StringPairDrag.h"
#include "TextFloat.h"
#include "ToolTip.h"
@@ -174,17 +175,6 @@ void vestigeInstrument::setParameter( void )
void vestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this )
{
if( QFileInfo( m_pluginDLL ).isAbsolute() )
{
QString f = QString( m_pluginDLL ).replace( QDir::separator(), '/' );
QString vd = QString( ConfigManager::inst()->vstDir() ).replace( QDir::separator(), '/' );
QString relativePath;
if( !( relativePath = f.section( vd, 1, 1 ) ).isEmpty() )
{
m_pluginDLL = relativePath;
}
}
_this.setAttribute( "plugin", m_pluginDLL );
m_pluginMutex.lock();
if( m_plugin != NULL )
@@ -254,8 +244,7 @@ void vestigeInstrument::loadFile( const QString & _file )
{
closePlugin();
}
m_pluginDLL = _file;
m_pluginDLL = SampleBuffer::tryToMakeRelative( _file );
TextFloat * tf = TextFloat::displayMessage(
tr( "Loading plugin" ),
tr( "Please wait while loading VST-plugin..." ),
@@ -269,6 +258,7 @@ void vestigeInstrument::loadFile( const QString & _file )
closePlugin();
delete tf;
collectErrorForUI( VstPlugin::tr( "The VST plugin %1 could not be loaded." ).arg( m_pluginDLL ) );
m_pluginDLL = "";
return;
}
@@ -425,10 +415,10 @@ VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument,
m_managePluginButton->setCheckable( false );
m_managePluginButton->setCursor( Qt::PointingHandCursor );
m_managePluginButton->move( 216, 101 );
m_managePluginButton->setActiveGraphic( embed::getIconPixmap(
"track_op_menu_active" ) );
m_managePluginButton->setInactiveGraphic( embed::getIconPixmap(
"track_op_menu" ) );
m_managePluginButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
"controls_active" ) );
m_managePluginButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
"controls" ) );
connect( m_managePluginButton, SIGNAL( clicked() ), this,
SLOT( managePlugin() ) );
ToolTip::add( m_managePluginButton, tr( "Control VST-plugin from LMMS host" ) );
@@ -614,29 +604,22 @@ void VestigeInstrumentView::openPlugin()
{
FileDialog ofd( NULL, tr( "Open VST-plugin" ) );
QString dir;
if( m_vi->m_pluginDLL != "" )
{
dir = QFileInfo( m_vi->m_pluginDLL ).absolutePath();
}
else
{
dir = ConfigManager::inst()->vstDir();
}
// change dir to position of previously opened file
ofd.setDirectory( dir );
ofd.setFileMode( FileDialog::ExistingFiles );
// set filters
QStringList types;
types << tr( "DLL-files (*.dll)" )
<< tr( "EXE-files (*.exe)" )
;
ofd.setNameFilters( types );
if( m_vi->m_pluginDLL != "" )
{
// select previously opened file
ofd.selectFile( QFileInfo( m_vi->m_pluginDLL ).fileName() );
QString f = SampleBuffer::tryToMakeAbsolute( m_vi->m_pluginDLL );
ofd.setDirectory( QFileInfo( f ).absolutePath() );
ofd.selectFile( QFileInfo( f ).fileName() );
}
else
{
ofd.setDirectory( ConfigManager::inst()->vstDir() );
}
if ( ofd.exec () == QDialog::Accepted )

View File

@@ -34,20 +34,20 @@ IF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE)
IF(LMMS_HOST_X86_64)
SET(EXTRA_FLAGS -m32)
# workaround for broken wineg++ in WINE 1.4 (shipped e.g. with Ubuntu Precise)
EXEC_PROGRAM( ${WINE_CXX} ARGS "-v -m32 /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT)
# workaround for broken wineg++ in WINE 1.4 (shipped e.g. with Ubuntu Precise)
IF("${WINEBUILD_OUTPUT}" MATCHES ".*x86_64-linux-gnu/wine/libwinecrt0.a.*")
SET(EXTRA_FLAGS ${EXTRA_FLAGS} -nodefaultlibs /usr/lib/i386-linux-gnu/wine/libwinecrt0.a -luser32 -lkernel32 -lgdi32)
SET(EXTRA_FLAGS ${EXTRA_FLAGS} -nodefaultlibs /usr/lib/i386-linux-gnu/wine/libwinecrt0.a -L/usr/lib/i386-linux-gnu/wine/ -luser32 -lkernel32 -lgdi32)
ENDIF()
# The following check works on Fedora systems
IF("${WINEBUILD_OUTPUT}" MATCHES "/usr/lib/lib64/wine/libwinecrt0.a.*")
SET(EXTRA_FLAGS ${EXTRA_FLAGS} -nodefaultlibs /usr/lib/i386/wine/libwinecrt0.a -luser32 -lkernel32 -lgdi32)
ENDIF()
# Development
# Wine development
IF("${WINEBUILD_OUTPUT}" MATCHES "/opt/wine-devel/lib64/wine/libwinecrt0.a.*")
SET(EXTRA_FLAGS ${EXTRA_FLAGS} -nodefaultlibs /opt/wine-devel/lib/wine/libwinecrt0.a -luser32 -lkernel32 -lgdi32)
ENDIF()
# Staging
# Wine staging
IF("${WINEBUILD_OUTPUT}" MATCHES "/opt/wine-staging/lib64/wine/libwinecrt0.a.*")
SET(EXTRA_FLAGS ${EXTRA_FLAGS} -nodefaultlibs /opt/wine-staging/lib/wine/libwinecrt0.a -luser32 -lkernel32 -lgdi32)
ENDIF()
@@ -61,16 +61,15 @@ STRING(REPLACE " " ";" WINE_BUILD_FLAGS ${CMAKE_CXX_FLAGS} " " ${CMAKE_EXE_LINKE
ADD_CUSTOM_COMMAND(
SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp"
COMMAND ${WINE_CXX}
ARGS "-I\"${CMAKE_BINARY_DIR}\""
"-I\"${CMAKE_SOURCE_DIR}/include\""
"-I\"${CMAKE_INSTALL_PREFIX}/include/wine/windows\""
"-I\"${CMAKE_INSTALL_PREFIX}/include\""
"-I\"${WINE_INCLUDE_BASE_DIR}\""
"-L\"${WINE_LIBRARY_DIR}\""
"\"${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp\""
ARGS -I${CMAKE_BINARY_DIR}
-I${CMAKE_SOURCE_DIR}/include
-I${WINE_INCLUDE_BASE_DIR}
-L${WINE_LIBRARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp
-ansi -mwindows -lpthread ${EXTRA_FLAGS} -fno-omit-frame-pointer
${WINE_BUILD_FLAGS}
-o ../RemoteVstPlugin
# Ensure correct file extension
COMMAND sh -c "mv ../RemoteVstPlugin.exe ../RemoteVstPlugin || true"
TARGET vstbase
OUTPUTS ../RemoteVstPlugin

View File

@@ -75,6 +75,10 @@ IF(NOT ("${OGGVORBIS_INCLUDE_DIR}" STREQUAL ""))
INCLUDE_DIRECTORIES("${OGGVORBIS_INCLUDE_DIR}")
ENDIF()
IF(NOT ("${LAME_INCLUDE_DIRS}" STREQUAL ""))
INCLUDE_DIRECTORIES("${LAME_INCLUDE_DIRS}")
ENDIF()
# Use libraries in non-standard directories (e.g., another version of Qt)
IF(LMMS_BUILD_LINUX)
LINK_LIBRARIES(-Wl,--enable-new-dtags)
@@ -136,6 +140,7 @@ SET(LMMS_REQUIRED_LIBS
${PULSEAUDIO_LIBRARIES}
${JACK_LIBRARIES}
${OGGVORBIS_LIBRARIES}
${LAME_LIBRARIES}
${SAMPLERATE_LIBRARIES}
${SNDFILE_LIBRARIES}
${EXTRA_LIBRARIES}
@@ -191,6 +196,7 @@ IF(LMMS_BUILD_WIN32)
"${MINGW_PREFIX}/bin/libvorbisfile-3.dll"
"${MINGW_PREFIX}/bin/libjpeg-9.dll"
"${MINGW_PREFIX}/bin/libogg-0.dll"
"${MINGW_PREFIX}/bin/libmp3lame-0.dll"
"${MINGW_PREFIX}/bin/libfftw3f-3.dll"
"${MINGW_PREFIX}/bin/libFLAC-8.dll"
"${MINGW_PREFIX}/bin/libpng16-16.dll"

View File

@@ -716,19 +716,19 @@ float AutomatableModel::globalAutomationValueAt( const MidiTime& time )
float FloatModel::getRoundedValue() const
{
return static_cast<float>( static_cast<int>( value() / step<float>() + 0.5 ) ) * step<float>();
return qRound( value() / step<float>() ) * step<float>();
}
float FloatModel::getDigitCount()
int FloatModel::getDigitCount() const
{
float steptemp = step<float>();
int digits = 0;
while ( steptemp < 1 )
{
steptemp = steptemp / 0.1f;
steptemp = steptemp * 10.0f;
digits++;
}
return digits;

View File

@@ -69,6 +69,7 @@ set(LMMS_SRCS
core/audio/AudioAlsa.cpp
core/audio/AudioDevice.cpp
core/audio/AudioFileDevice.cpp
core/audio/AudioFileMP3.cpp
core/audio/AudioFileOgg.cpp
core/audio/AudioFileWave.cpp
core/audio/AudioJack.cpp

View File

@@ -63,7 +63,12 @@ ConfigManager::ConfigManager() :
// If we're in development (lmms is not installed) let's get the source and
// binary directories by reading the CMake Cache
QFile cmakeCache(qApp->applicationDirPath() + "/CMakeCache.txt");
QDir appPath = qApp->applicationDirPath();
// If in tests, get parent directory
if (appPath.dirName() == "tests") {
appPath.cdUp();
}
QFile cmakeCache(appPath.absoluteFilePath("CMakeCache.txt"));
if (cmakeCache.exists()) {
cmakeCache.open(QFile::ReadOnly);
QTextStream stream(&cmakeCache);
@@ -277,7 +282,8 @@ void ConfigManager::addRecentlyOpenedProject( const QString & file )
{
QFileInfo recentFile( file );
if( recentFile.suffix().toLower() == "mmp" ||
recentFile.suffix().toLower() == "mmpz" )
recentFile.suffix().toLower() == "mmpz" ||
recentFile.suffix().toLower() == "mpt" )
{
m_recentlyOpenedProjects.removeAll( file );
if( m_recentlyOpenedProjects.size() > 50 )
@@ -313,6 +319,16 @@ const QString & ConfigManager::value( const QString & cls,
const QString & ConfigManager::value( const QString & cls,
const QString & attribute,
const QString & defaultVal ) const
{
const QString & val = value( cls, attribute );
return val.isEmpty() ? defaultVal : val;
}
void ConfigManager::setValue( const QString & cls,
const QString & attribute,

View File

@@ -113,6 +113,7 @@ void LfoController::updateValueBuffer()
}
m_currentPhase = absFraction( phase - m_phaseOffset );
m_bufferLastUpdated = s_periods;
}
void LfoController::updatePhase()

View File

@@ -30,6 +30,7 @@
#include "AudioFileWave.h"
#include "AudioFileOgg.h"
#include "AudioFileMP3.h"
#ifdef LMMS_HAVE_SCHED_H
#include "sched.h"
@@ -48,6 +49,15 @@ const ProjectRenderer::FileEncodeDevice ProjectRenderer::fileEncodeDevices[] =
&AudioFileOgg::getInst
#else
NULL
#endif
},
{ ProjectRenderer::MP3File,
QT_TRANSLATE_NOOP( "ProjectRenderer", "Compressed MP3-File (*.mp3)" ),
".mp3",
#ifdef LMMS_HAVE_MP3LAME
&AudioFileMP3::getInst
#else
NULL
#endif
},
// ... insert your own file-encoder-infos here... may be one day the
@@ -93,6 +103,8 @@ ProjectRenderer::ProjectRenderer( const Mixer::qualitySettings & qualitySettings
ProjectRenderer::~ProjectRenderer()
{
Engine::mixer()->restoreAudioDevice(); // also deletes audio-dev
Engine::mixer()->changeQuality( m_oldQualitySettings );
}
@@ -172,10 +184,11 @@ void ProjectRenderer::run()
m_progress = 0;
std::pair<MidiTime, MidiTime> exportEndpoints = Engine::getSong()->getExportEndpoints();
tick_t startTick = exportEndpoints.first.getTicks();
tick_t lengthTicks = exportEndpoints.second.getTicks() - startTick;
tick_t endTick = exportEndpoints.second.getTicks();
tick_t lengthTicks = endTick - startTick;
// Continually track and emit progress percentage to listeners
while( Engine::getSong()->isExportDone() == false &&
while( exportPos.getTicks() < endTick &&
Engine::getSong()->isExporting() == true
&& !m_abort )
{
@@ -190,12 +203,8 @@ void ProjectRenderer::run()
Engine::getSong()->stopExport();
const QString f = m_fileDev->outputFile();
Engine::mixer()->restoreAudioDevice(); // also deletes audio-dev
Engine::mixer()->changeQuality( m_oldQualitySettings );
// if the user aborted export-process, the file has to be deleted
const QString f = m_fileDev->outputFile();
if( m_abort )
{
QFile( f ).remove();

View File

@@ -1411,25 +1411,35 @@ void SampleBuffer::setReversed( bool _on )
QString SampleBuffer::tryToMakeRelative( const QString & _file )
QString SampleBuffer::tryToMakeRelative( const QString & file )
{
if( QFileInfo( _file ).isRelative() == false )
if( QFileInfo( file ).isRelative() == false )
{
QString f = QString( _file ).replace( QDir::separator(), '/' );
QString fsd = ConfigManager::inst()->factorySamplesDir();
QString usd = ConfigManager::inst()->userSamplesDir();
fsd.replace( QDir::separator(), '/' );
usd.replace( QDir::separator(), '/' );
if( f.startsWith( fsd ) )
QString f = QString( file ).replace( QDir::separator(), '/' );
// First, look in factory samples
// Isolate "samples/" from "data:/samples/"
QString samplesSuffix = ConfigManager::inst()->factorySamplesDir().mid( ConfigManager::inst()->dataDir().length() );
// Iterate over all valid "data:/" searchPaths
for ( const QString & path : QDir::searchPaths( "data" ) )
{
return QString( f ).mid( fsd.length() );
QString samplesPath = QString( path + samplesSuffix ).replace( QDir::separator(), '/' );
if ( f.startsWith( samplesPath ) )
{
return QString( f ).mid( samplesPath.length() );
}
}
else if( f.startsWith( usd ) )
// Next, look in user samples
QString usd = ConfigManager::inst()->userSamplesDir();
usd.replace( QDir::separator(), '/' );
if( f.startsWith( usd ) )
{
return QString( f ).mid( usd.length() );
}
}
return _file;
return file;
}

View File

@@ -464,29 +464,6 @@ void Song::processAutomations(const TrackList &tracklist, MidiTime timeStart, fp
}
}
bool Song::isExportDone() const
{
if ( m_renderBetweenMarkers )
{
return m_exporting == true &&
m_playPos[Mode_PlaySong].getTicks() >=
m_playPos[Mode_PlaySong].m_timeLine->loopEnd().getTicks();
}
if( m_exportLoop )
{
return m_exporting == true &&
m_playPos[Mode_PlaySong].getTicks() >=
length() * ticksPerTact();
}
else
{
return m_exporting == true &&
m_playPos[Mode_PlaySong].getTicks() >=
( length() + 1 ) * ticksPerTact();
}
}
std::pair<MidiTime, MidiTime> Song::getExportEndpoints() const
{
if ( m_renderBetweenMarkers )
@@ -1077,6 +1054,27 @@ void Song::loadProject( const QString & fileName )
}
node = dataFile.content().firstChild();
QDomNodeList tclist=dataFile.content().elementsByTagName("trackcontainer");
m_nLoadingTrack=0;
for( int i=0,n=tclist.count(); i<n; ++i )
{
QDomNode nd=tclist.at(i).firstChild();
while(!nd.isNull())
{
if( nd.isElement() && nd.nodeName() == "track" )
{
++m_nLoadingTrack;
if( nd.toElement().attribute("type").toInt() == Track::BBTrack )
{
n += nd.toElement().elementsByTagName("bbtrack").at(0)
.toElement().firstChildElement().childNodes().count();
}
nd=nd.nextSibling();
}
}
}
while( !node.isNull() )
{
if( node.isElement() )
@@ -1339,7 +1337,8 @@ void Song::exportProject( bool multiExport )
efd.setFileMode( FileDialog::AnyFile );
int idx = 0;
QStringList types;
while( ProjectRenderer::fileEncodeDevices[idx].m_fileFormat != ProjectRenderer::NumFileFormats )
while( ProjectRenderer::fileEncodeDevices[idx].m_fileFormat != ProjectRenderer::NumFileFormats &&
ProjectRenderer::fileEncodeDevices[idx].isAvailable())
{
types << tr( ProjectRenderer::fileEncodeDevices[idx].m_description );
++idx;
@@ -1360,13 +1359,14 @@ void Song::exportProject( bool multiExport )
efd.setWindowTitle( tr( "Select file for project-export..." ) );
}
QString suffix = "wav";
efd.setDefaultSuffix( suffix );
efd.setAcceptMode( FileDialog::AcceptSave );
if( efd.exec() == QDialog::Accepted && !efd.selectedFiles().isEmpty() &&
!efd.selectedFiles()[0].isEmpty() )
{
QString suffix = "";
QString exportFileName = efd.selectedFiles()[0];
if ( !multiExport )
{
@@ -1378,19 +1378,18 @@ void Song::exportProject( bool multiExport )
// Get first extension from selected dropdown.
// i.e. ".wav" from "WAV-File (*.wav), Dummy-File (*.dum)"
suffix = efd.selectedNameFilter().mid( stx + 2, etx - stx - 2 ).split( " " )[0].trimmed();
exportFileName.remove( "." + suffix, Qt::CaseInsensitive );
if ( efd.selectedFiles()[0].endsWith( suffix ) )
{
suffix = "";
if( VersionedSaveDialog::fileExistsQuery( exportFileName + suffix,
tr( "Save project" ) ) )
{
exportFileName += suffix;
}
}
}
}
if( VersionedSaveDialog::fileExistsQuery( exportFileName + suffix,
tr( "Save project" ) ) )
{
exportFileName += suffix;
}
ExportProjectDialog epd( exportFileName, gui->mainWindow(), multiExport );
epd.exec();
}

View File

@@ -86,25 +86,18 @@ void TrackContainer::loadSettings( const QDomElement & _this )
static QProgressDialog * pd = NULL;
bool was_null = ( pd == NULL );
int start_val = 0;
if( !journalRestore && gui != nullptr )
{
if( pd == NULL )
{
pd = new QProgressDialog( tr( "Loading project..." ),
tr( "Cancel" ), 0,
_this.childNodes().count(),
Engine::getSong()->getLoadingTrackCount(),
gui->mainWindow() );
pd->setWindowModality( Qt::ApplicationModal );
pd->setWindowTitle( tr( "Please wait..." ) );
pd->show();
}
else
{
start_val = pd->value();
pd->setMaximum( pd->maximum() +
_this.childNodes().count() );
}
}
QDomNode node = _this.firstChild();
@@ -124,6 +117,14 @@ void TrackContainer::loadSettings( const QDomElement & _this )
if( node.isElement() &&
!node.toElement().attribute( "metadata" ).toInt() )
{
QString trackName = node.toElement().hasAttribute( "name" ) ?
node.toElement().attribute( "name" ) :
node.firstChild().toElement().attribute( "name" );
if( pd != NULL )
{
pd->setLabelText( tr("Loading Track %1 (%2/Total %3)").arg( trackName ).
arg( pd->value() + 1 ).arg( Engine::getSong()->getLoadingTrackCount() ) );
}
Track::create( node.toElement(), this );
}
node = node.nextSibling();
@@ -131,7 +132,6 @@ void TrackContainer::loadSettings( const QDomElement & _this )
if( pd != NULL )
{
pd->setValue( start_val + _this.childNodes().count() );
if( was_null )
{
delete pd;

View File

@@ -0,0 +1,133 @@
/*
* AudioFileMP3.cpp - Audio-device which encodes a wave stream into
* an MP3 file. This is used for song export.
*
* Copyright (c) 2017 to present Michael Gregorius <michael.gregorius.git/at/arcor[dot]de>
*
* This file is part of LMMS - https://lmms.io
*
* 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 "AudioFileMP3.h"
#ifdef LMMS_HAVE_MP3LAME
#include "Mixer.h"
#include <cassert>
AudioFileMP3::AudioFileMP3( OutputSettings const & outputSettings,
const ch_cnt_t channels,
bool & successful,
const QString & file,
Mixer* mixer ) :
AudioFileDevice( outputSettings, channels, file, mixer )
{
successful = true;
// For now only accept stereo sources
successful &= channels == 2;
successful &= initEncoder();
successful &= outputFileOpened();
}
AudioFileMP3::~AudioFileMP3()
{
flushRemainingBuffers();
tearDownEncoder();
}
void AudioFileMP3::writeBuffer( const surroundSampleFrame * _buf,
const fpp_t _frames,
const float _master_gain )
{
if (_frames < 1)
{
return;
}
// TODO Why isn't the gain applied by the driver but inside the device?
std::vector<float> interleavedDataBuffer(_frames * 2);
for (fpp_t i = 0; i < _frames; ++i)
{
interleavedDataBuffer[2*i] = _buf[i][0] * _master_gain;
interleavedDataBuffer[2*i + 1] = _buf[i][1] * _master_gain;
}
size_t minimumBufferSize = 1.25 * _frames + 7200;
std::vector<unsigned char> encodingBuffer(minimumBufferSize);
int bytesWritten = lame_encode_buffer_interleaved_ieee_float(m_lame, &interleavedDataBuffer[0], _frames, &encodingBuffer[0], static_cast<int>(encodingBuffer.size()));
assert (bytesWritten >= 0);
writeData(&encodingBuffer[0], bytesWritten);
}
void AudioFileMP3::flushRemainingBuffers()
{
// The documentation states that flush should have at least 7200 bytes. So let's be generous.
std::vector<unsigned char> encodingBuffer(7200 * 4);
int bytesWritten = lame_encode_flush(m_lame, &encodingBuffer[0], static_cast<int>(encodingBuffer.size()));
assert (bytesWritten >= 0);
writeData(&encodingBuffer[0], bytesWritten);
}
MPEG_mode mapToMPEG_mode(OutputSettings::StereoMode stereoMode)
{
switch (stereoMode)
{
case OutputSettings::StereoMode_Stereo:
return STEREO;
case OutputSettings::StereoMode_JointStereo:
return JOINT_STEREO;
case OutputSettings::StereoMode_Mono:
return MONO;
default:
return NOT_SET;
}
}
bool AudioFileMP3::initEncoder()
{
m_lame = lame_init();
// Handle stereo/joint/mono settings
OutputSettings::StereoMode stereoMode = getOutputSettings().getStereoMode();
lame_set_mode(m_lame, mapToMPEG_mode(stereoMode));
// Handle bit rate settings
OutputSettings::BitRateSettings bitRateSettings = getOutputSettings().getBitRateSettings();
int bitRate = static_cast<int>(bitRateSettings.getBitRate());
lame_set_VBR(m_lame, vbr_off);
lame_set_brate(m_lame, bitRate);
// Add a comment
id3tag_set_comment(m_lame, "Created with LMMS");
return lame_init_params(m_lame) != -1;
}
void AudioFileMP3::tearDownEncoder()
{
lame_close(m_lame);
}
#endif

View File

@@ -70,8 +70,7 @@ inline int AudioFileOgg::writePage()
bool AudioFileOgg::startEncoding()
{
vorbis_comment vc;
const char * comments = "Cool=This song has been made using Linux "
"MultiMedia Studio";
const char * comments = "Cool=This song has been made using LMMS";
int comment_length = strlen( comments );
char * user_comments = new char[comment_length + 1];
strcpy( user_comments, comments );
@@ -100,7 +99,7 @@ bool AudioFileOgg::startEncoding()
m_rate = 48000;
setSampleRate( 48000 );
}
m_serialNo = 0; // track-num?
m_comments = &vc; // comments for ogg-file
// Have vorbisenc choose a mode for us
@@ -135,6 +134,10 @@ bool AudioFileOgg::startEncoding()
vorbis_analysis_init( &m_vd, &m_vi );
vorbis_block_init( &m_vd, &m_vb );
// We give our ogg file a random serial number and avoid
// 0 and UINT32_MAX which can get you into trouble.
qsrand( time( 0 ) );
m_serialNo = 0xD0000000 + qrand() % 0x0FFFFFFF;
ogg_stream_init( &m_os, m_serialNo );
// Now, build the three header packets and send through to the stream

View File

@@ -79,7 +79,12 @@ bool AudioFileWave::startEncoding()
outputFile().toUtf8().constData(),
#endif
SFM_WRITE, &m_si );
// Prevent fold overs when encountering clipped data
sf_command(m_sf, SFC_SET_CLIPPING, NULL, SF_TRUE);
sf_set_string ( m_sf, SF_STR_SOFTWARE, "LMMS" );
return true;
}

View File

@@ -160,7 +160,7 @@ int calc13octaveband31(float *absspec_buffer, float *subbands, int num_spec, flo
{
static const int onethirdoctavecenterfr[] = {20, 25, 31, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000, 10000, 12500, 16000, 20000};
int i, j;
float f_min, f_max, frequency, bandwith;
float f_min, f_max, frequency, bandwidth;
int j_min, j_max=0;
float fpower;
@@ -189,13 +189,13 @@ static const int onethirdoctavecenterfr[] = {20, 25, 31, 40, 50, 63, 80, 100, 12
{
subbands[i]=0;
// calculate bandwith for subband
// calculate bandwidth for subband
frequency=onethirdoctavecenterfr[i];
bandwith=(pow(2, 1.0/3.0)-1)*frequency;
bandwidth=(pow(2, 1.0/3.0)-1)*frequency;
f_min=frequency-bandwith/2.0;
f_max=frequency+bandwith/2.0;
f_min=frequency-bandwidth/2.0;
f_max=frequency+bandwidth/2.0;
j_min=(int)(f_min/max_frequency*(float)num_spec);

View File

@@ -151,6 +151,7 @@ void printHelp()
" [ -i <method> ]\n"
" [ --import <in> [-e]]\n"
" [ -l ]\n"
" [ -m <mode>]\n"
" [ -o <path> ]\n"
" [ -p <out> ]\n"
" [ -r <project file> ] [ options ]\n"
@@ -165,7 +166,7 @@ void printHelp()
"-c, --config <configfile> Get the configuration from <configfile>\n"
"-d, --dump <in> Dump XML of compressed file <in>\n"
"-f, --format <format> Specify format of render-output where\n"
" Format is either 'wav' or 'ogg'.\n"
" Format is either 'wav', 'ogg' or 'mp3'.\n"
" --geometry <geometry> Specify the size and position of the main window\n"
" geometry is <xsizexysize+xoffset+yoffsety>.\n"
"-h, --help Show this usage information and exit.\n"
@@ -178,6 +179,12 @@ void printHelp()
" --import <in> [-e] Import MIDI file <in>.\n"
" If -e is specified lmms exits after importing the file.\n"
"-l, --loop Render as a loop\n"
"-m, --mode Stereo mode used for MP3 export\n"
" Possible values: s, j, m\n"
" s: Stereo\n"
" j: Joint Stereo\n"
" m: Mono\n"
" Default: j\n"
"-o, --output <path> Render into <path>\n"
" For --render, provide a file path\n"
" For --rendertracks, provide a directory path\n"
@@ -291,7 +298,7 @@ int main( int argc, char * * argv )
{
printf( "LMMS cannot be run as root.\nUse \"--allowroot\" to override.\n\n" );
return EXIT_FAILURE;
}
}
#endif
QCoreApplication * app = coreOnly ?
@@ -299,7 +306,7 @@ int main( int argc, char * * argv )
new MainApplication( argc, argv );
Mixer::qualitySettings qs( Mixer::qualitySettings::Mode_HighQuality );
OutputSettings os( 44100, OutputSettings::BitRateSettings(160, false), OutputSettings::Depth_16Bit );
OutputSettings os( 44100, OutputSettings::BitRateSettings(160, false), OutputSettings::Depth_16Bit, OutputSettings::StereoMode_JointStereo );
ProjectRenderer::ExportFileFormats eff = ProjectRenderer::WaveFile;
// second of two command-line parsing stages
@@ -353,7 +360,7 @@ int main( int argc, char * * argv )
printf( "\nOption \"--allowroot\" will be ignored on this platform.\n\n" );
}
#endif
}
else if( arg == "--dump" || arg == "-d" )
{
@@ -430,6 +437,12 @@ int main( int argc, char * * argv )
{
eff = ProjectRenderer::OggFile;
}
#endif
#ifdef LMMS_HAVE_MP3LAME
else if( ext == "mp3" )
{
eff = ProjectRenderer::MP3File;
}
#endif
else
{
@@ -485,6 +498,38 @@ int main( int argc, char * * argv )
else
{
printf( "\nInvalid bitrate %s.\n\n"
"Try \"%s --help\" for more information.\n\n", argv[i], argv[0] );
return EXIT_FAILURE;
}
}
else if( arg == "--mode" || arg == "-m" )
{
++i;
if( i == argc )
{
printf( "\nNo stereo mode specified.\n\n"
"Try \"%s --help\" for more information.\n\n", argv[0] );
return EXIT_FAILURE;
}
QString const mode( argv[i] );
if( mode == "s" )
{
os.setStereoMode(OutputSettings::StereoMode_Stereo);
}
else if( mode == "j" )
{
os.setStereoMode(OutputSettings::StereoMode_JointStereo);
}
else if( mode == "m" )
{
os.setStereoMode(OutputSettings::StereoMode_Mono);
}
else
{
printf( "\nInvalid stereo mode %s.\n\n"
"Try \"%s --help\" for more information.\n\n", argv[i], argv[0] );
return EXIT_FAILURE;
}
@@ -778,10 +823,6 @@ int main( int argc, char * * argv )
" <td><b>%4</b></td>"
" <td>%5</td>"
" </tr>"
" <tr>"
" <td><b>%6</b></td>"
" <td>%7</td>"
" </tr>"
"</table>"
"</html>" ).arg(
MainWindow::tr( "There is a recovery file present. "
@@ -792,10 +833,6 @@ int main( int argc, char * * argv )
MainWindow::tr( "Recover" ),
MainWindow::tr( "Recover the file. Please don't run "
"multiple instances of LMMS when you do this." ),
MainWindow::tr( "Ignore" ),
MainWindow::tr( "Launch LMMS as usual but with "
"automatic backup disabled to prevent the "
"present recover file from being overwritten." ),
MainWindow::tr( "Discard" ),
MainWindow::tr( "Launch a default session and delete "
"the restored files. This is not reversible." )
@@ -807,38 +844,32 @@ int main( int argc, char * * argv )
QPushButton * recover;
QPushButton * discard;
QPushButton * ignore;
QPushButton * exit;
#if QT_VERSION >= 0x050000
// setting all buttons to the same roles allows us
// setting all buttons to the same roles allows us
// to have a custom layout
discard = mb.addButton( MainWindow::tr( "Discard" ),
QMessageBox::AcceptRole );
ignore = mb.addButton( MainWindow::tr( "Ignore" ),
QMessageBox::AcceptRole );
recover = mb.addButton( MainWindow::tr( "Recover" ),
QMessageBox::AcceptRole );
# else
# else
// in qt4 the button order is reversed
recover = mb.addButton( MainWindow::tr( "Recover" ),
QMessageBox::AcceptRole );
ignore = mb.addButton( MainWindow::tr( "Ignore" ),
QMessageBox::AcceptRole );
discard = mb.addButton( MainWindow::tr( "Discard" ),
QMessageBox::AcceptRole );
#endif
// have a hidden exit button
exit = mb.addButton( "", QMessageBox::RejectRole);
exit->setVisible(false);
// set icons
recover->setIcon( embed::getIconPixmap( "recover" ) );
discard->setIcon( embed::getIconPixmap( "discard" ) );
ignore->setIcon( embed::getIconPixmap( "ignore" ) );
mb.setDefaultButton( recover );
mb.setEscapeButton( exit );
@@ -853,13 +884,6 @@ int main( int argc, char * * argv )
fileToLoad = recoveryFile;
gui->mainWindow()->setSession( MainWindow::SessionState::Recover );
}
else if( mb.clickedButton() == ignore )
{
if( autoSaveEnabled )
{
gui->mainWindow()->setSession( MainWindow::SessionState::Limited );
}
}
else // Exit
{
return 0;
@@ -902,20 +926,19 @@ int main( int argc, char * * argv )
}
}
// If enabled, open last project if there is one. Else, create
// a new one. Also skip recently opened file if limited session to
// lower the chance of opening an already opened file.
// a new one.
else if( ConfigManager::inst()->
value( "app", "openlastproject" ).toInt() &&
!ConfigManager::inst()->
recentlyOpenedProjects().isEmpty() &&
gui->mainWindow()->getSession() !=
MainWindow::SessionState::Limited )
!recoveryFilePresent )
{
QString f = ConfigManager::inst()->
recentlyOpenedProjects().first();
QFileInfo recentFile( f );
if ( recentFile.exists() )
if ( recentFile.exists() &&
recentFile.suffix().toLower() != "mpt" )
{
Engine::getSong()->loadProject( f );
}
@@ -932,8 +955,7 @@ int main( int argc, char * * argv )
// Finally we start the auto save timer and also trigger the
// autosave one time as recover.mmp is a signal to possible other
// instances of LMMS.
if( autoSaveEnabled &&
gui->mainWindow()->getSession() != MainWindow::SessionState::Limited )
if( autoSaveEnabled )
{
gui->mainWindow()->autoSaveTimerReset();
gui->mainWindow()->autoSave();

View File

@@ -67,6 +67,11 @@ void MidiClient::addPort( MidiPort* port )
void MidiClient::removePort( MidiPort* port )
{
if( ! port )
{
return;
}
QVector<MidiPort *>::Iterator it =
qFind( m_midiPorts.begin(), m_midiPorts.end(), port );
if( it != m_midiPorts.end() )

View File

@@ -129,11 +129,11 @@ void MidiPort::processInEvent( const MidiEvent& event, const MidiTime& time )
{
return;
}
}
if( fixedInputVelocity() >= 0 && inEvent.velocity() > 0 )
{
inEvent.setVelocity( fixedInputVelocity() );
if( fixedInputVelocity() >= 0 && inEvent.velocity() > 0 )
{
inEvent.setVelocity( fixedInputVelocity() );
}
}
m_midiEventProcessor->processInEvent( inEvent, time );

View File

@@ -85,6 +85,7 @@ SET(LMMS_SRCS
gui/widgets/ToolButton.cpp
gui/widgets/ToolTip.cpp
gui/widgets/TrackLabelButton.cpp
gui/widgets/TrackRenameLineEdit.cpp
gui/widgets/VisualizationWidget.cpp
PARENT_SCOPE

View File

@@ -58,7 +58,7 @@ ExportProjectDialog::ExportProjectDialog( const QString & _file_name,
int cbIndex = 0;
for( int i = 0; i < ProjectRenderer::NumFileFormats; ++i )
{
if( ProjectRenderer::fileEncodeDevices[i].m_getDevInst != NULL )
if( ProjectRenderer::fileEncodeDevices[i].isAvailable() )
{
// get the extension of this format
QString renderExt = ProjectRenderer::fileEncodeDevices[i].m_extension;
@@ -128,7 +128,20 @@ void ExportProjectDialog::closeEvent( QCloseEvent * _ce )
}
OutputSettings::StereoMode mapToStereoMode(int index)
{
switch (index)
{
case 0:
return OutputSettings::StereoMode_Stereo;
case 1:
return OutputSettings::StereoMode_JointStereo;
case 2:
return OutputSettings::StereoMode_Mono;
default:
return OutputSettings::StereoMode_Stereo;
}
}
void ExportProjectDialog::startExport()
{
@@ -146,7 +159,8 @@ void ExportProjectDialog::startExport()
OutputSettings os = OutputSettings(
samplerates[ samplerateCB->currentIndex() ],
bitRateSettings,
static_cast<OutputSettings::BitDepth>( depthCB->currentIndex() ) );
static_cast<OutputSettings::BitDepth>( depthCB->currentIndex() ),
mapToStereoMode(stereoModeComboBox->currentIndex()) );
m_renderManager = new RenderManager( qs, os, m_ft, m_fileName );
@@ -181,6 +195,8 @@ ProjectRenderer::ExportFileFormats convertIndexToExportFileFormat(int index)
return ProjectRenderer::WaveFile;
case 1:
return ProjectRenderer::OggFile;
case 2:
return ProjectRenderer::MP3File;
default:
Q_ASSERT(false);
break;
@@ -195,10 +211,23 @@ void ExportProjectDialog::onFileFormatChanged(int index)
ProjectRenderer::ExportFileFormats exportFormat =
convertIndexToExportFileFormat(index);
bool bitRateControlsEnabled = exportFormat == ProjectRenderer::OggFile;
bool stereoModeVisible = exportFormat == ProjectRenderer::MP3File;
bool sampleRateControlsVisible = exportFormat != ProjectRenderer::MP3File;
bool bitRateControlsEnabled =
(exportFormat == ProjectRenderer::OggFile ||
exportFormat == ProjectRenderer::MP3File);
bool bitDepthControlEnabled = exportFormat == ProjectRenderer::WaveFile;
bool variableBitrateVisible = exportFormat != ProjectRenderer::MP3File;
stereoModeWidget->setVisible(stereoModeVisible);
sampleRateWidget->setVisible(sampleRateControlsVisible);
bitrateWidget->setVisible(bitRateControlsEnabled);
checkBoxVariableBitRate->setVisible(variableBitrateVisible);
depthWidget->setVisible(bitDepthControlEnabled);
}

View File

@@ -664,10 +664,6 @@ void MainWindow::resetWindowTitle()
{
title += " - " + tr( "Recover session. Please save your work!" );
}
if( getSession() == Limited )
{
title += " - " + tr( "Automatic backup disabled. Remember to save your work!" );
}
setWindowTitle( title + " - " + tr( "LMMS %1" ).arg( LMMS_VERSION ) );
}
@@ -738,7 +734,7 @@ void MainWindow::clearKeyModifiers()
void MainWindow::saveWidgetState( QWidget * _w, QDomElement & _de, QSize const & sizeIfInvisible )
void MainWindow::saveWidgetState( QWidget * _w, QDomElement & _de )
{
// If our widget is the main content of a window (e.g. piano roll, FxMixer, etc),
// we really care about the position of the *window* - not the position of the widget within its window
@@ -761,7 +757,7 @@ void MainWindow::saveWidgetState( QWidget * _w, QDomElement & _de, QSize const &
_de.setAttribute( "x", normalGeom.x() );
_de.setAttribute( "y", normalGeom.y() );
QSize sizeToStore = visible ? normalGeom.size() : sizeIfInvisible;
QSize sizeToStore = normalGeom.size();
_de.setAttribute( "width", sizeToStore.width() );
_de.setAttribute( "height", sizeToStore.height() );
}
@@ -773,8 +769,8 @@ void MainWindow::restoreWidgetState( QWidget * _w, const QDomElement & _de )
{
QRect r( qMax( 1, _de.attribute( "x" ).toInt() ),
qMax( 1, _de.attribute( "y" ).toInt() ),
qMax( 100, _de.attribute( "width" ).toInt() ),
qMax( 100, _de.attribute( "height" ).toInt() ) );
qMax( _w->sizeHint().width(), _de.attribute( "width" ).toInt() ),
qMax( _w->minimumHeight(), _de.attribute( "height" ).toInt() ) );
if( _de.hasAttribute( "visible" ) && !r.isNull() )
{
// If our widget is the main content of a window (e.g. piano roll, FxMixer, etc),
@@ -880,8 +876,8 @@ void MainWindow::updateRecentlyOpenedProjectsMenu()
m_recentlyOpenedProjectsMenu->clear();
QStringList rup = ConfigManager::inst()->recentlyOpenedProjects();
// The file history goes 30 deep but we only show the 15
// most recent ones that we can open.
// The file history goes 50 deep but we only show the 15
// most recent ones that we can open and omit .mpt files.
int shownInMenu = 0;
for( QStringList::iterator it = rup.begin(); it != rup.end(); ++it )
{
@@ -889,6 +885,11 @@ void MainWindow::updateRecentlyOpenedProjectsMenu()
if ( recentFile.exists() &&
*it != ConfigManager::inst()->recoveryFile() )
{
if( recentFile.suffix().toLower() == "mpt" )
{
continue;
}
m_recentlyOpenedProjectsMenu->addAction(
embed::getIconPixmap( "project_file" ), *it );
#ifdef LMMS_BUILD_APPLE
@@ -1374,8 +1375,8 @@ void MainWindow::closeEvent( QCloseEvent * _ce )
if( mayChangeProject(true) )
{
// delete recovery file
if( ConfigManager::inst()->value( "ui", "enableautosave" ).toInt()
&& getSession() != Limited )
if( ConfigManager::inst()->
value( "ui", "enableautosave" ).toInt() )
{
sessionCleanup();
_ce->accept();
@@ -1562,8 +1563,7 @@ void MainWindow::autoSave()
// from the timer where we need to do extra tests.
void MainWindow::runAutoSave()
{
if( ConfigManager::inst()->value( "ui", "enableautosave" ).toInt() &&
getSession() != Limited )
if( ConfigManager::inst()->value( "ui", "enableautosave" ).toInt() )
{
autoSave();
autoSaveTimerReset(); // Reset timer

View File

@@ -119,8 +119,8 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
#endif
m_backgroundArtwork( QDir::toNativeSeparators( ConfigManager::inst()->backgroundArtwork() ) ),
m_smoothScroll( ConfigManager::inst()->value( "ui", "smoothscroll" ).toInt() ),
m_enableAutoSave( ConfigManager::inst()->value( "ui", "enableautosave" ).toInt() ),
m_enableRunningAutoSave( ConfigManager::inst()->value( "ui", "enablerunningautosave" ).toInt() ),
m_enableAutoSave( ConfigManager::inst()->value( "ui", "enableautosave", "1" ).toInt() ),
m_enableRunningAutoSave( ConfigManager::inst()->value( "ui", "enablerunningautosave", "1" ).toInt() ),
m_saveInterval( ConfigManager::inst()->value( "ui", "saveinterval" ).toInt() < 1 ?
MainWindow::DEFAULT_SAVE_INTERVAL_MINUTES :
ConfigManager::inst()->value( "ui", "saveinterval" ).toInt() ),
@@ -131,7 +131,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
m_syncVSTPlugins( ConfigManager::inst()->value( "ui",
"syncvstplugins" ).toInt() ),
m_animateAFP(ConfigManager::inst()->value( "ui",
"animateafp").toInt() ),
"animateafp", "1" ).toInt() ),
m_printNoteLabels(ConfigManager::inst()->value( "ui",
"printnotelabels").toInt() ),
m_displayWaveform(ConfigManager::inst()->value( "ui",

View File

@@ -94,6 +94,8 @@ TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt,
connect( updateTimer, SIGNAL( timeout() ),
this, SLOT( updatePosition() ) );
updateTimer->start( 50 );
connect( Engine::getSong(), SIGNAL( timeSignatureChanged( int,int ) ),
this, SLOT( update() ) );
}

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>715</width>
<height>447</height>
<height>491</height>
</rect>
</property>
<property name="minimumSize">
@@ -45,39 +45,48 @@
<widget class="QComboBox" name="fileFormatCB"/>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Samplerate:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="samplerateCB">
<item>
<property name="text">
<string>44100 Hz</string>
<widget class="QWidget" name="sampleRateWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>0</number>
</property>
</item>
<item>
<property name="text">
<string>48000 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>88200 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>96000 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>192000 Hz</string>
</property>
</item>
<item>
<widget class="QLabel" name="labelSampleRate">
<property name="text">
<string>Samplerate:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="samplerateCB">
<item>
<property name="text">
<string>44100 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>48000 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>88200 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>96000 Hz</string>
</property>
</item>
<item>
<property name="text">
<string>192000 Hz</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
@@ -124,6 +133,44 @@
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="stereoModeWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelStereoMode_3">
<property name="text">
<string>Stereo mode:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="stereoModeComboBox">
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>Stereo</string>
</property>
</item>
<item>
<property name="text">
<string>Joint Stereo</string>
</property>
</item>
<item>
<property name="text">
<string>Mono</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="bitrateWidget" native="true">
<layout class="QVBoxLayout">

View File

@@ -69,7 +69,7 @@ QPixmap * AutomationEditor::s_toolYFlip = NULL;
QPixmap * AutomationEditor::s_toolXFlip = NULL;
const QVector<double> AutomationEditor::m_zoomXLevels =
{ 8.0f, 4.0f, 2.0f, 1.0f, 0.5f, 0.25f, 0.125f };
{ 0.125f, 0.25f, 0.5f, 1.0f, 2.0f, 4.0f, 8.0f };
@@ -239,7 +239,7 @@ void AutomationEditor::setCurrentPattern(AutomationPattern * new_pattern )
void AutomationEditor::saveSettings(QDomDocument & doc, QDomElement & dom_parent)
{
MainWindow::saveWidgetState(parentWidget(), dom_parent, QSize( 640, 400 ));
MainWindow::saveWidgetState( parentWidget(), dom_parent );
}
@@ -1233,18 +1233,20 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
}
}
// alternating shades for better contrast
// count the bars which disappear on left by scrolling
float timeSignature = static_cast<float>( Engine::getSong()->getTimeSigModel().getNumerator() )
/ static_cast<float>( Engine::getSong()->getTimeSigModel().getDenominator() );
float zoomFactor = m_zoomXLevels[m_zoomingXModel.value()];
int barCount = m_currentPosition / MidiTime::ticksPerTact();
int leftBars = m_currentPosition * zoomFactor / m_ppt;
//the bars which disappears at the left side by scrolling
int leftBars = m_currentPosition * zoomFactor / MidiTime::ticksPerTact();
for( int x = VALUES_WIDTH; x < width() + m_currentPosition * zoomFactor; x += m_ppt, ++barCount )
//iterates the visible bars and draw the shading on uneven bars
for( int x = VALUES_WIDTH, barCount = leftBars; x < width() + m_currentPosition * zoomFactor / timeSignature; x += m_ppt, ++barCount )
{
if( ( barCount + leftBars ) % 2 != 0 )
{
p.fillRect( x - m_currentPosition * zoomFactor, TOP_MARGIN, m_ppt,
p.fillRect( x - m_currentPosition * zoomFactor / timeSignature, TOP_MARGIN, m_ppt,
height() - ( SCROLLBAR_SIZE + TOP_MARGIN ), backgroundShade() );
}
}
@@ -1301,7 +1303,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
//Don't bother doing/rendering anything if there is no automation points
if( time_map.size() > 0 )
{
timeMap::iterator it = time_map.begin();
timeMap::iterator it = time_map.begin();
while( it+1 != time_map.end() )
{
// skip this section if it occurs completely before the
@@ -1318,7 +1320,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
{
break;
}
//NEEDS Change in CSS
/*bool is_selected = false;
// if we're in move-mode, we may only draw
@@ -1358,8 +1360,8 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
for( int i = 0; i < ( it + 1 ).key() - it.key(); i++ )
{ path.lineTo( QPointF( xCoordOfTick( it.key() + i ), yCoordOfLevel( values[i] ) ) );
//NEEDS Change in CSS
//drawLevelTick( p, it.key() + i, values[i], is_selected );
//drawLevelTick( p, it.key() + i, values[i], is_selected );
}
path.lineTo( QPointF( xCoordOfTick( ( it + 1 ).key() ), yCoordOfLevel( nextValue ) ) );
path.lineTo( QPointF( xCoordOfTick( ( it + 1 ).key() ), yCoordOfLevel( 0 ) ) );
@@ -1535,12 +1537,12 @@ void AutomationEditor::drawLevelTick(QPainter & p, int tick, float value)
p.fillRect( x, y_start, rect_width, rect_height, currentColor );
}
else
{
printf("not in range\n");
}
}
@@ -1598,12 +1600,12 @@ void AutomationEditor::wheelEvent(QWheelEvent * we )
{
y++;
}
if( we->delta() < 0 )
else if( we->delta() < 0 )
{
y--;
}
y = qBound( 0, y, m_zoomingYModel.size() - 1 );
m_zoomingYModel.setValue( y );
m_zoomingYModel.setValue( y );
}
else if( we->modifiers() & Qt::ControlModifier && we->modifiers() & Qt::AltModifier )
{
@@ -1612,7 +1614,7 @@ void AutomationEditor::wheelEvent(QWheelEvent * we )
{
q--;
}
if( we->delta() < 0 )
else if( we->delta() < 0 )
{
q++;
}
@@ -1624,13 +1626,13 @@ void AutomationEditor::wheelEvent(QWheelEvent * we )
{
int x = m_zoomingXModel.value();
if( we->delta() > 0 )
{
x--;
}
if( we->delta() < 0 )
{
x++;
}
else if( we->delta() < 0 )
{
x--;
}
x = qBound( 0, x, m_zoomingXModel.size() - 1 );
m_zoomingXModel.setValue( x );
}

View File

@@ -237,7 +237,7 @@ void BBTrackContainerView::removeBBView(int bb)
void BBTrackContainerView::saveSettings(QDomDocument& doc, QDomElement& element)
{
MainWindow::saveWidgetState(parentWidget(), element, QSize( 640, 400 ) );
MainWindow::saveWidgetState( parentWidget(), element );
}
void BBTrackContainerView::loadSettings(const QDomElement& element)

View File

@@ -143,7 +143,7 @@ PianoRoll::PianoRollKeyTypes PianoRoll::prKeyOrder[] =
const int DEFAULT_PR_PPT = KEY_LINE_HEIGHT * DefaultStepsPerTact;
const QVector<double> PianoRoll::m_zoomLevels =
{ 8.0f, 4.0f, 2.0f, 1.0f, 0.5f, 0.25f, 0.125f };
{ 0.125f, 0.25f, 0.5f, 1.0f, 2.0f, 4.0f, 8.0f };
PianoRoll::PianoRoll() :
@@ -805,7 +805,7 @@ void PianoRoll::setBackgroundShade( const QColor & c )
void PianoRoll::drawNoteRect( QPainter & p, int x, int y,
void PianoRoll::drawNoteRect( QPainter & p, int x, int y,
int width, const Note * n, const QColor & noteCol,
const QColor & selCol, const int noteOpc, const bool borders )
{
@@ -997,6 +997,7 @@ void PianoRoll::shiftPos( int amount ) //shift notes pos by amount
}
m_pattern->rearrangeAllNotes();
m_pattern->updateLength();
m_pattern->dataChanged();
// we modified the song
@@ -1917,7 +1918,7 @@ void PianoRoll::mouseReleaseEvent( QMouseEvent * me )
{
// select the notes within the selection rectangle and
// then destroy the selection rectangle
computeSelectedNotes(
computeSelectedNotes(
me->modifiers() & Qt::ShiftModifier );
}
else if( m_action == ActionMoveNote )
@@ -2459,15 +2460,10 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
note->setPos( MidiTime( pos_ticks ) );
note->setKey( key_num );
// If dragging beat notes check if pattern should be MelodyPattern
if( note->length() < 0 )
{
m_pattern->checkType();
}
}
}
}
}
}
else if (m_action == ActionResizeNote)
{
// When resizing notes:
@@ -2475,7 +2471,7 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
// If shift is pressed we resize and rearrange only the selected notes
// If shift + ctrl then we also rearrange all posterior notes (sticky)
// If shift is pressed but only one note is selected, apply sticky
if (shift)
{
// Algorithm:
@@ -2495,8 +2491,8 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
const Note *posteriorNote = nullptr;
for (const Note *note : notes)
{
if (note->selected() && (posteriorNote == nullptr ||
note->oldPos().getTicks() + note->oldLength().getTicks() >
if (note->selected() && (posteriorNote == nullptr ||
note->oldPos().getTicks() + note->oldLength().getTicks() >
posteriorNote->oldPos().getTicks() + posteriorNote->oldLength().getTicks()))
{
posteriorNote = note;
@@ -2516,9 +2512,9 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
if(note->selected())
{
// scale relative start and end positions by scaleFactor
int newStart = stretchStartTick + scaleFactor *
int newStart = stretchStartTick + scaleFactor *
(note->oldPos().getTicks() - stretchStartTick);
int newEnd = stretchStartTick + scaleFactor *
int newEnd = stretchStartTick + scaleFactor *
(note->oldPos().getTicks()+note->oldLength().getTicks() - stretchStartTick);
// if not holding alt, quantize the offsets
if(!alt)
@@ -2537,7 +2533,7 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
int newLength = qMax(1, newEnd-newStart);
if (note == posteriorNote)
{
posteriorDeltaThisFrame = (newStart+newLength) -
posteriorDeltaThisFrame = (newStart+newLength) -
(note->pos().getTicks() + note->length().getTicks());
}
note->setLength( MidiTime(newLength) );
@@ -2892,18 +2888,20 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
++key;
}
// Draw alternating shades on bars
// count the bars which disappear on left by scrolling
float timeSignature = static_cast<float>( Engine::getSong()->getTimeSigModel().getNumerator() )
/ static_cast<float>( Engine::getSong()->getTimeSigModel().getDenominator() );
float zoomFactor = m_zoomLevels[m_zoomingModel.value()];
int barCount = m_currentPosition / MidiTime::ticksPerTact();
int leftBars = m_currentPosition * zoomFactor / m_ppt;
//the bars which disappears at the left side by scrolling
int leftBars = m_currentPosition * zoomFactor / MidiTime::ticksPerTact();
for( int x = WHITE_KEY_WIDTH; x < width() + m_currentPosition * zoomFactor; x += m_ppt, ++barCount )
//iterates the visible bars and draw the shading on uneven bars
for( int x = WHITE_KEY_WIDTH, barCount = leftBars; x < width() + m_currentPosition * zoomFactor / timeSignature; x += m_ppt, ++barCount )
{
if( ( barCount + leftBars ) % 2 != 0 )
{
p.fillRect( x - m_currentPosition * zoomFactor, PR_TOP_MARGIN, m_ppt,
p.fillRect( x - m_currentPosition * zoomFactor / timeSignature, PR_TOP_MARGIN, m_ppt,
height() - ( PR_BOTTOM_MARGIN + PR_TOP_MARGIN ), backgroundShade() );
}
}
@@ -3258,7 +3256,7 @@ void PianoRoll::wheelEvent(QWheelEvent * we )
{
q--;
}
if( we->delta() < 0 )
else if( we->delta() < 0 )
{
q++;
}
@@ -3272,7 +3270,7 @@ void PianoRoll::wheelEvent(QWheelEvent * we )
{
l--;
}
if( we->delta() < 0 )
else if( we->delta() < 0 )
{
l++;
}
@@ -3283,13 +3281,13 @@ void PianoRoll::wheelEvent(QWheelEvent * we )
{
int z = m_zoomingModel.value();
if( we->delta() > 0 )
{
z--;
}
if( we->delta() < 0 )
{
z++;
}
else if( we->delta() < 0 )
{
z--;
}
z = qBound( 0, z, m_zoomingModel.size() - 1 );
// update combobox with zooming-factor
m_zoomingModel.setValue( z );
@@ -3920,27 +3918,32 @@ int PianoRoll::quantization() const
void PianoRoll::quantizeNotes()
{
if( ! hasValidPattern() )
{
return;
}
NoteVector notes = getSelectedNotes();
if (notes.empty())
if( notes.empty() )
{
for (Note* n : m_pattern->notes())
for( Note* n : m_pattern->notes() )
{
notes.push_back(n);
notes.push_back( n );
}
}
for (Note* n : notes)
for( Note* n : notes )
{
if (n->length() == MidiTime(0))
if( n->length() == MidiTime( 0 ) )
{
continue;
}
Note copy(*n);
m_pattern->removeNote(n);
copy.quantizePos(quantization());
m_pattern->addNote(copy);
m_pattern->removeNote( n );
copy.quantizePos( quantization() );
m_pattern->addNote( copy );
}
update();
@@ -4389,7 +4392,7 @@ void PianoRollWindow::reset()
void PianoRollWindow::saveSettings( QDomDocument & doc, QDomElement & de )
{
MainWindow::saveWidgetState( this, de, QSize( 640, 480 ) );
MainWindow::saveWidgetState( this, de );
}

View File

@@ -71,7 +71,7 @@ void positionLine::paintEvent( QPaintEvent * pe )
}
const QVector<double> SongEditor::m_zoomLevels =
{ 16.0f, 8.0f, 4.0f, 2.0f, 1.0f, 0.5f, 0.25f, 0.125f };
{ 0.125f, 0.25f, 0.5f, 1.0f, 2.0f, 4.0f, 8.0f, 16.0f };
SongEditor::SongEditor( Song * song ) :
@@ -262,7 +262,7 @@ SongEditor::~SongEditor()
void SongEditor::saveSettings( QDomDocument& doc, QDomElement& element )
{
MainWindow::saveWidgetState(parentWidget(), element, QSize( 640, 400 ));
MainWindow::saveWidgetState( parentWidget(), element );
}
void SongEditor::loadSettings( const QDomElement& element )
@@ -360,13 +360,13 @@ void SongEditor::wheelEvent( QWheelEvent * we )
int z = m_zoomingModel->value();
if( we->delta() > 0 )
{
z--;
}
if( we->delta() < 0 )
{
z++;
}
else if( we->delta() < 0 )
{
z--;
}
z = qBound( 0, z, m_zoomingModel->size() - 1 );
// update combobox with zooming-factor
m_zoomingModel->setValue( z );
@@ -586,6 +586,14 @@ void SongEditor::updatePosition( const MidiTime & t )
void SongEditor::updatePositionLine()
{
m_positionLine->setFixedHeight( height() );
}
void SongEditor::zoomingChanged()
{
setPixelsPerTact( m_zoomLevels[m_zoomingModel->value()] * DEFAULT_PIXELS_PER_TACT );
@@ -697,6 +705,7 @@ SongEditorWindow::SongEditorWindow(Song* song) :
zoomToolBar->addWidget( m_zoomingComboBox );
connect(song, SIGNAL(projectLoaded()), this, SLOT(adjustUiAfterProjectLoad()));
connect(this, SIGNAL(resized()), m_editor, SLOT(updatePositionLine()));
}
QSize SongEditorWindow::sizeHint() const
@@ -705,6 +714,14 @@ QSize SongEditorWindow::sizeHint() const
}
void SongEditorWindow::resizeEvent(QResizeEvent *event)
{
emit resized();
}
void SongEditorWindow::play()
{
emit playTriggered();

View File

@@ -102,7 +102,7 @@ ControllerRackView::~ControllerRackView()
void ControllerRackView::saveSettings( QDomDocument & _doc,
QDomElement & _this )
{
MainWindow::saveWidgetState( this, _this, QSize( 400, 300) );
MainWindow::saveWidgetState( this, _this );
}

View File

@@ -39,7 +39,7 @@ EffectRackView::EffectRackView( EffectChain* model, QWidget* parent ) :
ModelView( NULL, this )
{
QVBoxLayout* mainLayout = new QVBoxLayout( this );
mainLayout->setMargin( 0 );
mainLayout->setMargin( 5 );
m_effectsGroupBox = new GroupBox( tr( "EFFECTS CHAIN" ) );
mainLayout->addWidget( m_effectsGroupBox );

Some files were not shown because too many files have changed in this diff Show More