Merge branch 'master' into cmake_dist

# Conflicts:
#	include/ConfigManager.h
#	include/Engine.h
#	plugins/CMakeLists.txt
#	plugins/vst_base/CMakeLists.txt
#	plugins/vst_base/Win64/CMakeLists.txt
#	src/core/Engine.cpp
This commit is contained in:
Lukas W committed 2015-05-30 22:59:06 +02:00
commit 422fbbc8d3
95 files changed
+1439 -761

No files matched your search

+1 -1
View File
@@ -6,7 +6,7 @@ matrix:
- env: TARGET_OS=win64
- os: osx
before_install:
- sh ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.before_install.sh
- sh ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.before_install.sh
install:
- sh ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.install.sh
before_script:
+1 -1
View File
@@ -15,7 +15,7 @@ INCLUDE(FindPkgConfig)
SET(VERSION_MAJOR "1")
SET(VERSION_MINOR "1")
SET(VERSION_PATCH "0")
SET(VERSION_PATCH "3")
#SET(VERSION_SUFFIX "")
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
IF(VERSION_SUFFIX)
+2 -2
View File
@@ -3435,7 +3435,7 @@ Per favor, comprova que tens permís d'escriptura per a aquest fitxer i tor
<translation type="unfinished">Obre projecte existent</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation type="unfinished">Projecte obert recentment</translation>
</message>
<message>
@@ -5936,7 +5936,7 @@ Latència: %2 ms</translation>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished"></translation>
</message>
<message>
+2 -2
View File
@@ -3435,7 +3435,7 @@ Ujistěte se prosím, že máte k souboru právo zápisu a zkuste to znovu.</tra
<translation type="unfinished">Otevřít existující projekt</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation type="unfinished">Naposledy otevřené projekty</translation>
</message>
<message>
@@ -5938,7 +5938,7 @@ Zpoždění %2 ms</translation>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">Ztlumený</translation>
</message>
<message>
+2 -2
View File
@@ -3456,7 +3456,7 @@ Bitte überprüfen Sie Ihre Rechte und versuchen es erneut.</translation>
<translation>Existierendes Projekt öffnen</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation>Zuletzt geöffnete Projekte</translation>
</message>
<message>
@@ -5974,7 +5974,7 @@ Latenz: %2 ms</translation>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">Stumm</translation>
</message>
<message>
+2 -2
View File
@@ -3433,7 +3433,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -5927,7 +5927,7 @@ Latency: %2 ms</source>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished"></translation>
</message>
<message>
+2 -2
View File
@@ -3433,7 +3433,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation type="unfinished">Abrir proyecto existente</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -5927,7 +5927,7 @@ Latency: %2 ms</source>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished"></translation>
</message>
<message>
+2 -2
View File
@@ -3433,7 +3433,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation type="unfinished">باز کردن پروژه ی موجود</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -5927,7 +5927,7 @@ Latency: %2 ms</source>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished"></translation>
</message>
<message>
+2 -2
View File
@@ -3448,7 +3448,7 @@ Veuillez vérifier que vous avez les droits d&apos;accès en écriture pour ce f
<translation>Ouvrir un projet existant</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation>Projets ouverts récemment</translation>
</message>
<message>
@@ -5947,7 +5947,7 @@ Veuillez vérifier que vous avez les droits en lecture pour ce fichier et le ré
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">Coupée</translation>
</message>
<message>
+2 -2
View File
@@ -3448,7 +3448,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation>Abrir un projecto existente</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation>Proxecto aberto recentemente</translation>
</message>
<message>
@@ -5946,7 +5946,7 @@ Latencia: %2 ms</translation>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">Silenciado</translation>
</message>
<message>
+2 -2
View File
@@ -3456,7 +3456,7 @@ Assicurati di avere i permessi in scrittura per il file e riprova.</translation>
<translation>Apri un progetto esistente</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation>Progetti aperti di recente</translation>
</message>
<message>
@@ -5971,7 +5971,7 @@ Assicurati di avere almeno i permessi di lettura del file e prova di nuovo.</tra
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">Muto</translation>
</message>
<message>
+2 -2
View File
@@ -3450,7 +3450,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation type="unfinished">既存プロジェクトを開く</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation type="unfinished">最近開いたプロジェクト</translation>
</message>
<message>
@@ -5950,7 +5950,7 @@ Latency: %2 ms</source>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">ミュート</translation>
</message>
<message>
+2 -2
View File
@@ -3433,7 +3433,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation type="unfinished">기존 프로젝트 열기</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation type="unfinished">최근 열린 프로젝트</translation>
</message>
<message>
@@ -5932,7 +5932,7 @@ Latency: %2 ms</source>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">무음</translation>
</message>
<message>
+2 -2
View File
@@ -3433,7 +3433,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation type="unfinished">Open bestaand project</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -5929,7 +5929,7 @@ Vertraging: %2 ms</translation>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished"></translation>
</message>
<message>
+2 -2
View File
@@ -3453,7 +3453,7 @@ Upewnij się, że masz prawo zapisu do tego pliku i spróbuj ponownie.</translat
<translation>Otwórz istniejący projekt</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation>Ostatnio otwierane projekty</translation>
</message>
<message>
@@ -5952,7 +5952,7 @@ Upewnij się, że masz przynajmniej uprawnienia odczytu tego pliku a następnie
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">Wyciszone</translation>
</message>
<message>
+2 -2
View File
@@ -3489,7 +3489,7 @@ Double click to pick a file.</source>
<translation>Mostrar/esconder Editor de Automação</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation>Projetos usados recentemente</translation>
</message>
<message>
@@ -5950,7 +5950,7 @@ Latência: %2 ms</translation>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">Mudo</translation>
</message>
<message>
+2 -2
View File
@@ -3477,7 +3477,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation>Открыть существующий проект</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation>Недавние проекты</translation>
</message>
<message>
@@ -6003,7 +6003,7 @@ Latency: %2 ms</source>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation>Тихо</translation>
</message>
<message>
+2 -2
View File
@@ -3433,7 +3433,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation type="unfinished">Öppna existerande projekt</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -5928,7 +5928,7 @@ Latency: %2 ms</source>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished"></translation>
</message>
<message>
+78 -78
View File
@@ -55,15 +55,15 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
</message>
<message>
<source>LMMS</source>
<translation type="unfinished">LMMS</translation>
<translation>LMMS</translation>
</message>
<message>
<source>Involved</source>
<translation type="unfinished"></translation>
<translation>参与者</translation>
</message>
<message>
<source>Contributors ordered by number of commits:</source>
<translation type="unfinished"></translation>
<translation>贡献者名单(以提交次数排序):</translation>
</message>
</context>
<context>
@@ -151,7 +151,7 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
</message>
<message>
<source>Amplify:</source>
<translation>放大: </translation>
<translation type="unfinished">放大:</translation>
</message>
<message>
<source>With this knob you can set the amplify ratio. When you set a value of 100% your sample isn&apos;t changed. Otherwise it will be amplified up or down (your actual sample-file isn&apos;t touched!)</source>
@@ -203,7 +203,7 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
</message>
<message>
<source>Loopback point:</source>
<translation type="unfinished"></translation>
<translation>循环点:</translation>
</message>
<message>
<source>With this knob you can set the point where the loop starts. </source>
@@ -237,11 +237,11 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
</message>
<message>
<source>CLIENT-NAME</source>
<translation type="unfinished">客户端名称</translation>
<translation>客户端名称</translation>
</message>
<message>
<source>CHANNELS</source>
<translation type="unfinished">声道数</translation>
<translation>声道数</translation>
</message>
</context>
<context>
@@ -335,7 +335,7 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
<name>AutomationEditor</name>
<message>
<source>Please open an automation pattern with the context menu of a control!</source>
<translation type="unfinished"></translation>
<translation>请使用控制的上下文菜单打开一个自动控制样式!</translation>
</message>
<message>
<source>Values copied</source>
@@ -350,35 +350,35 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
<name>AutomationEditorWindow</name>
<message>
<source>Play/pause current pattern (Space)</source>
<translation type="unfinished">播放/暂停当前片段(空格)</translation>
<translation>播放/暂停当前片段(空格)</translation>
</message>
<message>
<source>Click here if you want to play the current pattern. This is useful while editing it. The pattern is automatically looped when the end is reached.</source>
<translation type="unfinished">点击这里播放片段。编辑时很有用,片段会自动循环播放。</translation>
<translation>点击这里播放片段。编辑时很有用,片段会自动循环播放。</translation>
</message>
<message>
<source>Stop playing of current pattern (Space)</source>
<translation type="unfinished">停止当前片段(空格)</translation>
<translation>停止当前片段(空格)</translation>
</message>
<message>
<source>Click here if you want to stop playing of the current pattern.</source>
<translation type="unfinished">点击这里停止播放片段。</translation>
<translation>点击这里停止播放片段。</translation>
</message>
<message>
<source>Draw mode (Shift+D)</source>
<translation type="unfinished">绘制模式 (Shift+D)</translation>
<translation>绘制模式 (Shift+D)</translation>
</message>
<message>
<source>Erase mode (Shift+E)</source>
<translation type="unfinished">擦除模式 (Shift+E)</translation>
<translation>擦除模式 (Shift+E)</translation>
</message>
<message>
<source>Flip vertically</source>
<translation type="unfinished"></translation>
<translation>垂直翻转</translation>
</message>
<message>
<source>Flip horizontally</source>
<translation type="unfinished"></translation>
<translation>水平翻转</translation>
</message>
<message>
<source>Click here and the pattern will be inverted.The points are flipped in the y direction. </source>
@@ -530,31 +530,31 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
<name>BBEditor</name>
<message>
<source>Beat+Bassline Editor</source>
<translation type="unfinished">节拍+低音线编辑器</translation>
<translation type="unfinished">节拍+Bassline编辑器</translation>
</message>
<message>
<source>Play/pause current beat/bassline (Space)</source>
<translation type="unfinished">播放/暂停当前节拍/低音线(空格)</translation>
<translation type="unfinished">播放/暂停当前节拍/Bassline(空格)</translation>
</message>
<message>
<source>Stop playback of current beat/bassline (Space)</source>
<translation type="unfinished">停止播放当前节拍/低音线(空格)</translation>
<translation type="unfinished">停止播放当前节拍/Bassline(空格)</translation>
</message>
<message>
<source>Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached.</source>
<translation type="unfinished">点击这里停止播放当前节拍/低音线。当结束时节拍/低音线会自动循环播放。</translation>
<translation type="unfinished">点击这里停止播放当前节拍/Bassline。当结束时节拍/Bassline会自动循环播放。</translation>
</message>
<message>
<source>Click here to stop playing of current beat/bassline.</source>
<translation type="unfinished">点击这里停止播发当前节拍/低音线。</translation>
<translation type="unfinished">点击这里停止播发当前节拍/Bassline。</translation>
</message>
<message>
<source>Add beat/bassline</source>
<translation type="unfinished">添加节拍/低音线</translation>
<translation type="unfinished">添加节拍/Bassline</translation>
</message>
<message>
<source>Add automation-track</source>
<translation type="unfinished"></translation>
<translation>添加自动控制轨道</translation>
</message>
<message>
<source>Remove steps</source>
@@ -569,7 +569,7 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
<name>BBTCOView</name>
<message>
<source>Open in Beat+Bassline-Editor</source>
<translation type="unfinished">在节拍+低音线编辑器中打开</translation>
<translation type="unfinished">在节拍+Bassline编辑器中打开</translation>
</message>
<message>
<source>Reset name</source>
@@ -592,7 +592,7 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
<name>BBTrack</name>
<message>
<source>Beat/Bassline %1</source>
<translation type="unfinished">节拍/低音线 %1</translation>
<translation type="unfinished">节拍/Bassline %1</translation>
</message>
<message>
<source>Clone of %1</source>
@@ -728,11 +728,11 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
<name>CaptionMenu</name>
<message>
<source>&amp;Help</source>
<translation type="unfinished"></translation>
<translation>帮助(&amp;H)</translation>
</message>
<message>
<source>Help (not available)</source>
<translation type="unfinished"></translation>
<translation>帮助(不可用)</translation>
</message>
</context>
<context>
@@ -1132,26 +1132,26 @@ Jeff Bai,邮箱:jeffbaichina@gmail.com</translation>
<name>DummyEffect</name>
<message>
<source>NOT FOUND</source>
<translation type="unfinished"></translation>
<translation>未找到</translation>
</message>
</context>
<context>
<name>Editor</name>
<message>
<source>Play (Space)</source>
<translation type="unfinished"></translation>
<translation>播放(空格)</translation>
</message>
<message>
<source>Stop (Space)</source>
<translation type="unfinished"></translation>
<translation>停止(空格)</translation>
</message>
<message>
<source>Record</source>
<translation type="unfinished"></translation>
<translation>录音</translation>
</message>
<message>
<source>Record while playing</source>
<translation type="unfinished"></translation>
<translation>播放时录音</translation>
</message>
</context>
<context>
@@ -1344,7 +1344,7 @@ Right clicking will bring up a context menu where you can change the order in wh
<name>EnvelopeAndLfoView</name>
<message>
<source>DEL</source>
<translation type="unfinished"></translation>
<translation>DEL</translation>
</message>
<message>
<source>Predelay:</source>
@@ -3177,7 +3177,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri
</message>
<message>
<source>Please enter a new value between %1 and %2:</source>
<translation type="unfinished"></translation>
<translation>请输入一个介于%1和%2之间的数值:</translation>
</message>
</context>
<context>
@@ -3224,7 +3224,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri
<name>LcdSpinBox</name>
<message>
<source>Please enter a new value between %1 and %2:</source>
<translation type="unfinished"></translation>
<translation>请输入一个介于%1和%2之间的数值:</translation>
</message>
</context>
<context>
@@ -3298,7 +3298,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri
</message>
<message>
<source>Modulation amount:</source>
<translation type="unfinished">调制量</translation>
<translation type="unfinished">调制量:</translation>
</message>
<message>
<source>Use this knob for setting modulation amount of the LFO. The bigger this value, the more the connected control (e.g. volume or cutoff-frequency) will be influenced by the LFO.</source>
@@ -3443,7 +3443,7 @@ Please make sure you have write-access to the file and try again.</source>
<translation>打开已有工程</translation>
</message>
<message>
<source>Recently opened project</source>
<source>Recently opened projects</source>
<translation>最近打开的工程</translation>
</message>
<message>
@@ -3557,12 +3557,12 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS.</source>
<translation>重做</translation>
</message>
<message>
<source>LMMS Project</source>
<source>LMMS Project</source>
<translation>LMMS 工程</translation>
</message>
<message>
<source>LMMS Project Template</source>
<translation>LMMS 工程模板</translation>
<source>LMMS Project Template</source>
<translation>LMMS 工程模板</translation>
</message>
<message>
<source>Volumes</source>
@@ -4399,15 +4399,15 @@ PM means phase modulation: Oscillator 3&apos;s phase is modulated by oscillator
</message>
<message>
<source>Step length:</source>
<translation type="unfinished"></translation>
<translation type="unfinished">步进长度:</translation>
</message>
<message>
<source>Dry</source>
<translation type="unfinished"></translation>
<translation type="unfinished">干声</translation>
</message>
<message>
<source>Dry Gain:</source>
<translation type="unfinished"></translation>
<translation type="unfinished">干声增益:</translation>
</message>
<message>
<source>Stages</source>
@@ -4674,11 +4674,11 @@ use mouse wheel to set volume of a step</source>
</message>
<message>
<source>Modulation amount:</source>
<translation type="unfinished">调制量</translation>
<translation type="unfinished">调制量:</translation>
</message>
<message>
<source>Attack:</source>
<translation type="unfinished">打进声</translation>
<translation type="unfinished">打进声:</translation>
</message>
<message>
<source>Release:</source>
@@ -5654,7 +5654,7 @@ Latency: %2 ms</source>
</message>
<message>
<source>untitled</source>
<translation type="unfinished">有标题</translation>
<translation>未标题</translation>
</message>
<message>
<source>Select file for project-export...</source>
@@ -5662,7 +5662,7 @@ Latency: %2 ms</source>
</message>
<message>
<source>The following errors occured while loading: </source>
<translation type="unfinished"></translation>
<translation>载入时发生以下错误:</translation>
</message>
</context>
<context>
@@ -5742,51 +5742,51 @@ Latency: %2 ms</source>
<name>SongEditorWindow</name>
<message>
<source>Song-Editor</source>
<translation type="unfinished">歌曲编辑器</translation>
<translation>歌曲编辑器</translation>
</message>
<message>
<source>Play song (Space)</source>
<translation type="unfinished">播放歌曲(空格)</translation>
<translation>播放歌曲(空格)</translation>
</message>
<message>
<source>Record samples from Audio-device</source>
<translation type="unfinished">从音频设备录制样本</translation>
<translation>从音频设备录制样本</translation>
</message>
<message>
<source>Record samples from Audio-device while playing song or BB track</source>
<translation type="unfinished">在播放歌曲或BB轨道时从音频设备录入样本</translation>
<translation>在播放歌曲或BB轨道时从音频设备录入样本</translation>
</message>
<message>
<source>Stop song (Space)</source>
<translation type="unfinished">停止歌曲(空格)</translation>
<translation>停止歌曲(空格)</translation>
</message>
<message>
<source>Add beat/bassline</source>
<translation type="unfinished">添加节拍/低音线</translation>
<translation>添加节拍/Bassline</translation>
</message>
<message>
<source>Add sample-track</source>
<translation type="unfinished">添加采样轨道</translation>
<translation>添加采样轨道</translation>
</message>
<message>
<source>Add automation-track</source>
<translation type="unfinished"></translation>
<translation>添加自动控制轨道</translation>
</message>
<message>
<source>Draw mode</source>
<translation type="unfinished">绘制模式</translation>
<translation>绘制模式</translation>
</message>
<message>
<source>Edit mode (select and move)</source>
<translation type="unfinished">编辑模式(选定和移动)</translation>
<translation>编辑模式(选定和移动)</translation>
</message>
<message>
<source>Click here, if you want to play your whole song. Playing will be started at the song-position-marker (green). You can also move it while playing.</source>
<translation type="unfinished">点击这里完整播放歌曲。将从绿色歌曲标记开始播放。在播放的同时可以对它进行移动。</translation>
<translation>点击这里完整播放歌曲。将从绿色歌曲标记开始播放。在播放的同时可以对它进行移动。</translation>
</message>
<message>
<source>Click here, if you want to stop playing of your song. The song-position-marker will be set to the start of your song.</source>
<translation type="unfinished">点击这里停止播放,歌曲位置标记会跳到歌曲的开头。</translation>
<translation>点击这里停止播放,歌曲位置标记会跳到歌曲的开头。</translation>
</message>
</context>
<context>
@@ -5942,7 +5942,7 @@ Latency: %2 ms</source>
<context>
<name>Track</name>
<message>
<source>Muted</source>
<source>Mute</source>
<translation type="unfinished">静音</translation>
</message>
<message>
@@ -6250,7 +6250,7 @@ Please make sure you have read-permission to the file and the directory containi
<name>VestigeInstrumentView</name>
<message>
<source>Open other VST-plugin</source>
<translation type="unfinished"></translation>
<translation type="unfinished">打开其他的VST插件</translation>
</message>
<message>
<source>Click here, if you want to open another VST-plugin. After clicking on this button, a file-open-dialog appears and you can select your file.</source>
@@ -6258,19 +6258,19 @@ Please make sure you have read-permission to the file and the directory containi
</message>
<message>
<source>Show/hide GUI</source>
<translation type="unfinished"></translation>
<translation type="unfinished">显示/隐藏界面</translation>
</message>
<message>
<source>Click here to show or hide the graphical user interface (GUI) of your VST-plugin.</source>
<translation type="unfinished"></translation>
<translation type="unfinished">点此显示/隐藏VST插件的界面。</translation>
</message>
<message>
<source>Turn off all notes</source>
<translation type="unfinished"></translation>
<translation type="unfinished">全部静音</translation>
</message>
<message>
<source>Open VST-plugin</source>
<translation type="unfinished"></translation>
<translation type="unfinished">打开VST插件</translation>
</message>
<message>
<source>DLL-files (*.dll)</source>
@@ -6282,7 +6282,7 @@ Please make sure you have read-permission to the file and the directory containi
</message>
<message>
<source>No VST-plugin loaded</source>
<translation type="unfinished"></translation>
<translation type="unfinished">未载入VST插件</translation>
</message>
<message>
<source>Control VST-plugin from LMMS host</source>
@@ -6326,7 +6326,7 @@ Please make sure you have read-permission to the file and the directory containi
</message>
<message>
<source>Preset</source>
<translation type="unfinished"></translation>
<translation type="unfinished">预置</translation>
</message>
<message>
<source>by </source>
@@ -6334,7 +6334,7 @@ Please make sure you have read-permission to the file and the directory containi
</message>
<message>
<source> - VST plugin control</source>
<translation type="unfinished"></translation>
<translation type="unfinished"> - VST插件控制</translation>
</message>
</context>
<context>
@@ -6352,7 +6352,7 @@ Please make sure you have read-permission to the file and the directory containi
<name>VstEffectControlDialog</name>
<message>
<source>Show/hide</source>
<translation type="unfinished"></translation>
<translation type="unfinished">显示/隐藏</translation>
</message>
<message>
<source>Control VST-plugin from LMMS host</source>
@@ -6400,7 +6400,7 @@ Please make sure you have read-permission to the file and the directory containi
</message>
<message>
<source>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
</context>
<context>
@@ -6411,15 +6411,15 @@ Please make sure you have read-permission to the file and the directory containi
</message>
<message>
<source>Open Preset</source>
<translation type="unfinished"></translation>
<translation type="unfinished">打开预置</translation>
</message>
<message>
<source>Vst Plugin Preset (*.fxp *.fxb)</source>
<translation type="unfinished"></translation>
<translation type="unfinished">VST插件预置文件(*.fxp *.fxb)</translation>
</message>
<message>
<source>: default</source>
<translation type="unfinished"></translation>
<translation type="unfinished">: 默认</translation>
</message>
<message>
<source>&quot;</source>
@@ -6431,7 +6431,7 @@ Please make sure you have read-permission to the file and the directory containi
</message>
<message>
<source>Save Preset</source>
<translation type="unfinished"></translation>
<translation type="unfinished">保存预置</translation>
</message>
<message>
<source>.fxp</source>
@@ -6451,11 +6451,11 @@ Please make sure you have read-permission to the file and the directory containi
</message>
<message>
<source>Please wait while loading VST plugin...</source>
<translation type="unfinished"></translation>
<translation type="unfinished">正在载入VST插件,请稍候……</translation>
</message>
<message>
<source>The VST plugin %1 could not be loaded.</source>
<translation type="unfinished"></translation>
<translation type="unfinished">无法载入VST插件 %1。</translation>
</message>
</context>
<context>
@@ -8565,7 +8565,7 @@ This chip was used in the Commodore 64 computer.</source>
</message>
<message>
<source>Patch</source>
<translation type="unfinished"></translation>
<translation type="unfinished">音色</translation>
</message>
<message>
<source>Gain</source>
@@ -8613,7 +8613,7 @@ This chip was used in the Commodore 64 computer.</source>
</message>
<message>
<source>A soundfont %1 could not be loaded.</source>
<translation type="unfinished"></translation>
<translation type="unfinished">无法载入Soundfont %1。</translation>
</message>
</context>
<context>
Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

+4
View File
@@ -45,7 +45,11 @@ public:
#ifdef LMMS_HAVE_PORTAUDIO
#if defined(__FreeBSD__)
#include <portaudio2/portaudio.h>
#else
#include <portaudio.h>
#endif
#include "AudioDevice.h"
+1 -1
View File
@@ -255,7 +255,7 @@ public:
// has to be accessed by more than one object, then this function shouldn't be used.
bool isValueChanged()
{
if( m_valueChanged )
if( m_valueChanged || valueBuffer() )
{
m_valueChanged = false;
return true;
+1 -1
View File
@@ -56,7 +56,7 @@ public:
AutomationPattern( const AutomationPattern & _pat_to_copy );
virtual ~AutomationPattern();
void addObject( AutomatableModel * _obj, bool _search_dup = true );
bool addObject( AutomatableModel * _obj, bool _search_dup = true );
const AutomatableModel * firstObject() const;
+43
View File
@@ -41,8 +41,12 @@ class Engine;
const QString PROJECTS_PATH = "projects/";
const QString TEMPLATE_PATH = "templates/";
const QString PRESETS_PATH = "presets/";
const QString SAMPLES_PATH = "samples/";
const QString GIG_PATH = "samples/gig/";
const QString SF2_PATH = "samples/sf2/";
const QString LADSPA_PATH ="plugins/ladspa/";
const QString DEFAULT_THEME_PATH = "themes/default/";
const QString TRACK_ICON_PATH = "track_icons/";
const QString LOCALE_PATH = "locale/";
@@ -76,6 +80,11 @@ public:
return workingDir() + PROJECTS_PATH;
}
QString userTemplateDir() const
{
return workingDir() + TEMPLATE_PATH;
}
QString userPresetsDir() const
{
return workingDir() + PRESETS_PATH;
@@ -86,6 +95,26 @@ public:
return workingDir() + SAMPLES_PATH;
}
QString userGigDir() const
{
return workingDir() + GIG_PATH;
}
QString userSf2Dir() const
{
return workingDir() + SF2_PATH;
}
QString userLadspaDir() const
{
return workingDir() + LADSPA_PATH;
}
QString userVstDir() const
{
return m_vstDir;
}
QString factoryProjectsDir() const
{
return dataDir() + PROJECTS_PATH;
@@ -126,6 +155,16 @@ public:
return m_dataDir + LOCALE_PATH;
}
const QString & gigDir() const
{
return m_gigDir;
}
const QString & sf2Dir() const
{
return m_sf2Dir;
}
const QString & vstDir() const
{
return m_vstDir;
@@ -195,6 +234,8 @@ public:
void setSTKDir( const QString & _fd );
void setDefaultSoundfont( const QString & _sf );
void setBackgroundArtwork( const QString & _ba );
void setGIGDir( const QString & gd );
void setSF2Dir( const QString & sfd );
private:
@@ -214,6 +255,8 @@ private:
QString m_vstDir;
QString m_flDir;
QString m_ladDir;
QString m_gigDir;
QString m_sf2Dir;
QString m_version;
#ifdef LMMS_HAVE_STK
QString m_stkDir;
+21 -1
View File
@@ -27,6 +27,9 @@
#define ENGINE_H
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QObject>
#include "export.h"
@@ -39,8 +42,9 @@ class Song;
class Ladspa2LMMS;
class EXPORT Engine
class EXPORT Engine : public QObject
{
Q_OBJECT
public:
static void init();
static void destroy();
@@ -91,6 +95,19 @@ public:
}
static void updateFramesPerTick();
static inline Engine * inst()
{
if( s_instanceOfMe == NULL )
{
s_instanceOfMe = new Engine();
}
return s_instanceOfMe;
}
signals:
void initProgress(const QString &msg);
private:
// small helper function which sets the pointer to NULL before actually deleting
// the object it refers to
@@ -114,6 +131,9 @@ private:
static Ladspa2LMMS * s_ladspaManager;
// even though most methods are static, an instance is needed for Qt slots/signals
static Engine * s_instanceOfMe;
friend class GuiApplication;
};
+2 -4
View File
@@ -100,14 +100,12 @@ private:
int knobPosY() const
{
float fRange = m_model->maxValue() - m_model->minValue();
float realVal = m_model->value() - m_model->minValue();
float fRange = model()->maxValue() - model()->minValue();
float realVal = model()->value() - model()->minValue();
return height() - ( ( height() - m_knob->height() ) * ( realVal / fRange ) );
}
FloatModel * m_model;
void setPeak( float fPeak, float &targetPeak, float &persistentPeak, QTime &lastPeakTime );
int calculateDisplayPeak( float fPeak );
+2
View File
@@ -58,6 +58,8 @@ public slots:
void filterItems( const QString & filter );
void reloadTree( void );
private slots:
void giveFocusToFilter();
private:
bool filterItems( QTreeWidgetItem * item, const QString & filter );
+3
View File
@@ -53,6 +53,8 @@ public:
public:
FxChannelView(QWidget * _parent, FxMixerView * _mv, int _chIndex );
void setChannelIndex( int index );
FxLine * m_fxLine;
PixmapButton * m_muteBtn;
PixmapButton * m_soloBtn;
@@ -97,6 +99,7 @@ public:
// move the channel to the left or right
void moveChannelLeft(int index);
void moveChannelLeft(int index, int focusIndex);
void moveChannelRight(int index);
// make sure the display syncs up with the fx mixer.
+10 -1
View File
@@ -25,8 +25,12 @@
#ifndef GUIAPPLICATION_H
#define GUIAPPLICATION_H
#include <QtCore/QObject>
#include "export.h"
class QLabel;
class AutomationEditorWindow;
class BBEditor;
class ControllerRackView;
@@ -36,8 +40,9 @@ class PianoRollWindow;
class ProjectNotes;
class SongEditorWindow;
class EXPORT GuiApplication
class EXPORT GuiApplication : public QObject
{
Q_OBJECT;
public:
explicit GuiApplication();
~GuiApplication();
@@ -53,6 +58,9 @@ public:
AutomationEditorWindow* automationEditor() { return m_automationEditor; }
ControllerRackView* getControllerRackView() { return m_controllerRackView; }
public slots:
void displayInitProgress(const QString &msg);
private:
static GuiApplication* s_instance;
@@ -64,6 +72,7 @@ private:
PianoRollWindow* m_pianoRoll;
ProjectNotes* m_projectNotes;
ControllerRackView* m_controllerRackView;
QLabel* m_loadingProgressLabel;
};
#define gui GuiApplication::instance()
-1
View File
@@ -84,7 +84,6 @@ public:
private:
Instrument* m_instrument;
InstrumentTrack * m_instrumentTrack;
} ;
+5 -1
View File
@@ -52,6 +52,7 @@ class InstrumentMidiIOView;
class InstrumentMiscView;
class Knob;
class LcdSpinBox;
class LeftRightNav;
class midiPortMenu;
class DataFile;
class PluginView;
@@ -416,16 +417,19 @@ protected:
protected slots:
void saveSettingsBtnClicked();
void viewNextInstrument();
void viewPrevInstrument();
private:
virtual void modelChanged();
void viewInstrumentInDirection(int d);
InstrumentTrack * m_track;
InstrumentTrackView * m_itv;
// widgets on the top of an instrument-track-window
QLineEdit * m_nameLineEdit;
LeftRightNav * m_leftRightNav;
Knob * m_volumeKnob;
Knob * m_panningKnob;
Knob * m_pitchKnob;
+49
View File
@@ -0,0 +1,49 @@
/*
* LeftRightNav.cpp - side-by-side left-facing and right-facing arrows for navigation (looks like < > )
*
* Copyright (c) 2015 Colin Wallace <wallacoloo/at/gmail.com>
*
* This file is part of LMMS - http://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 LEFT_RIGHT_NAV_H
#define LEFT_RIGHT_NAV_H
#include "PixmapButton.h"
#include <QLayout>
class LeftRightNav : public QWidget
{
Q_OBJECT
public:
LeftRightNav(QWidget *parent=NULL);
PixmapButton* getLeftBtn();
PixmapButton* getRightBtn();
void setShortcuts(const QKeySequence &leftShortcut=Qt::Key_Minus, const QKeySequence &rightShortcut=Qt::Key_Plus);
signals:
void onNavLeft();
void onNavRight();
private:
QHBoxLayout m_layout;
PixmapButton m_leftBtn;
PixmapButton m_rightBtn;
};
#endif
+4
View File
@@ -121,6 +121,7 @@ public slots:
void updatePlayPauseIcons();
void updateUndoRedoButtons();
void undo();
void redo();
@@ -167,6 +168,8 @@ private:
} m_keyMods;
QMenu * m_toolsMenu;
QAction * m_undoAction;
QAction * m_redoAction;
QList<PluginView *> m_tools;
QBasicTimer m_updateTimer;
@@ -190,6 +193,7 @@ private slots:
signals:
void periodicUpdate();
void initProgress(const QString &msg);
} ;
+1 -7
View File
@@ -25,13 +25,7 @@
#ifndef MIXER_H
#define MIXER_H
// denormals stripping
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#ifdef __SSE3__
#include <pmmintrin.h>
#endif
#include "denormals.h"
#include "lmmsconfig.h"
+2
View File
@@ -384,6 +384,8 @@ signals:
void currentPatternChanged();
private:
void focusInEvent(QFocusEvent * event);
PianoRoll* m_editor;
ComboBox * m_zoomingComboBox;
+1
View File
@@ -42,6 +42,7 @@ public:
void setActiveGraphic( const QPixmap & _pm );
void setInactiveGraphic( const QPixmap & _pm, bool _update = true );
QSize sizeHint() const;
signals:
void doubleClicked();
+3
View File
@@ -45,6 +45,9 @@ public:
void undo();
void redo();
bool canUndo() const;
bool canRedo() const;
void addJournalCheckPoint( JournallingObject *jo );
bool isJournalling() const
+9
View File
@@ -1,3 +1,4 @@
/*
* SetupDialog.h - dialog for setting up LMMS
*
@@ -71,6 +72,8 @@ private slots:
// path settings widget
void setWorkingDir( const QString & _wd );
void setVSTDir( const QString & _vd );
void setGIGDir( const QString & _gd );
void setSF2Dir( const QString & _sfd );
void setArtworkDir( const QString & _ad );
void setFLDir( const QString & _fd );
void setLADSPADir( const QString & _ld );
@@ -96,6 +99,8 @@ private slots:
void openWorkingDir();
void openVSTDir();
void openGIGDir();
void openSF2Dir();
void openArtworkDir();
void openFLDir();
void openLADSPADir();
@@ -138,6 +143,8 @@ private:
QLineEdit * m_adLineEdit;
QLineEdit * m_fdLineEdit;
QLineEdit * m_ladLineEdit;
QLineEdit * m_gigLineEdit;
QLineEdit * m_sf2LineEdit;
#ifdef LMMS_HAVE_FLUIDSYNTH
QLineEdit * m_sfLineEdit;
#endif
@@ -151,6 +158,8 @@ private:
QString m_artworkDir;
QString m_flDir;
QString m_ladDir;
QString m_gigDir;
QString m_sf2Dir;
#ifdef LMMS_HAVE_FLUIDSYNTH
QString m_defaultSoundfont;
#endif
-5
View File
@@ -57,7 +57,6 @@ public:
{
Mode_None,
Mode_PlaySong,
Mode_PlayTrack,
Mode_PlayBB,
Mode_PlayPattern,
Mode_PlayAutomationPattern,
@@ -75,7 +74,6 @@ public:
PlayPos( const int abs = 0 ) :
MidiTime( abs ),
m_timeLine( NULL ),
m_timeLineUpdate( true ),
m_currentFrame( 0.0f )
{
}
@@ -88,7 +86,6 @@ public:
return m_currentFrame;
}
TimeLineWidget * m_timeLine;
bool m_timeLineUpdate;
private:
float m_currentFrame;
@@ -258,7 +255,6 @@ public slots:
void playSong();
void record();
void playAndRecord();
void playTrack( Track * trackToPlay );
void playBB();
void playPattern( const Pattern * patternToPlay, bool loop = true );
void togglePause();
@@ -355,7 +351,6 @@ private:
PlayPos m_playPos[Mode_Count];
tact_t m_length;
Track * m_trackToPlay;
const Pattern* m_patternToPlay;
bool m_loopPattern;
+1 -1
View File
@@ -441,7 +441,7 @@ public:
static Track * create( TrackTypes tt, TrackContainer * tc );
static Track * create( const QDomElement & element,
TrackContainer * tc );
void clone();
Track * clone();
// pure virtual functions
+10 -8
View File
@@ -103,8 +103,15 @@ public:
return m_tc;
}
void moveTrackViewUp( TrackView * _tv );
void moveTrackViewDown( TrackView * _tv );
const QList<TrackView *> & trackViews() const
{
return( m_trackViews );
}
void moveTrackView( TrackView * trackView, int indexTo );
void moveTrackViewUp( TrackView * trackView );
void moveTrackViewDown( TrackView * trackView );
void scrollToTrackView( TrackView * _tv );
// -- for usage by trackView only ---------------
TrackView * addTrackView( TrackView * _tv );
@@ -121,7 +128,7 @@ public:
public slots:
void realignTracks();
void createTrackView( Track * _t );
TrackView * createTrackView( Track * _t );
void deleteTrackView( TrackView * _tv );
virtual void dropEvent( QDropEvent * _de );
@@ -141,11 +148,6 @@ public slots:
protected:
static const int DEFAULT_PIXELS_PER_TACT = 16;
const QList<TrackView *> & trackViews() const
{
return( m_trackViews );
}
virtual void mousePressEvent( QMouseEvent * _me );
virtual void mouseMoveEvent( QMouseEvent * _me );
virtual void mouseReleaseEvent( QMouseEvent * _me );
+32
View File
@@ -0,0 +1,32 @@
// Denormals stripping.
// These snippets should be common enough to be considered public domain.
#ifndef DENORMALS_H
#define DENORMALS_H
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#ifdef __SSE3__
#include <pmmintrin.h>
#endif
// Set denormal protection for this thread.
// To be on the safe side, don't set the DAZ flag for SSE2 builds,
// even if most SSE2 CPUs can handle it.
void inline disable_denormals() {
#ifdef __SSE3__
/* DAZ flag */
_MM_SET_DENORMALS_ZERO_MODE( _MM_DENORMALS_ZERO_ON );
#endif
#ifdef __SSE__
/* FTZ flag */
_MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
#endif
}
#endif
+1 -1
View File
@@ -34,7 +34,7 @@
#include <cmath>
using namespace std;
#if defined (LMMS_BUILD_WIN32) || defined (LMMS_BUILD_APPLE) || defined(LMMS_BUILD_HAIKU)
#if defined (LMMS_BUILD_WIN32) || defined (LMMS_BUILD_APPLE) || defined(LMMS_BUILD_HAIKU) || defined (__FreeBSD__)
#ifndef isnanf
#define isnanf(x) isnan(x)
#endif
+4
View File
@@ -1,6 +1,10 @@
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
INCLUDE_DIRECTORIES(
${SAMPLERATE_INCLUDE_DIRS}
)
ADD_SUBDIRECTORY(Amplifier)
ADD_SUBDIRECTORY(audio_file_processor)
ADD_SUBDIRECTORY(BassBooster)
+3 -3
View File
@@ -32,10 +32,10 @@
DelayControls::DelayControls( DelayEffect* effect ):
EffectControls( effect ),
m_effect ( effect ),
m_delayTimeModel( 0.5, 0.01, 20.0, 0.0001, 20000.0, this, tr( "Delay Samples" )) ,
m_delayTimeModel( 0.5, 0.01, 5.0, 0.0001, 20000.0, this, tr( "Delay Samples" )) ,
m_feedbackModel(0.0f,0.0f,1.0f,0.01f,this,tr( "Feedback" ) ),
m_lfoTimeModel(2.0, 0.01, 20.0, 0.0001, 20000.0, this, tr( "Lfo Frequency" ) ),
m_lfoAmountModel(0.0, 0.0, 2.0, 0.0001, 2000.0, this, tr ( "Lfo Amount" ) ),
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" ) ),
m_outGainModel( 0.0, -60.0, 20.0, 0.01, this, tr( "Output gain" ) )
{
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( changeSampleRate() ) );
+1 -1
View File
@@ -118,7 +118,7 @@ bool DelayEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
m_delay->setFeedback( *feedbackPtr );
m_lfo->setFrequency( *lfoTimePtr );
sampleLength = *lengthPtr * Engine::mixer()->processingSampleRate();
m_currentLength = linearInterpolate( sampleLength, m_currentLength, 0.9999 );
m_currentLength = sampleLength;
m_delay->setLength( m_currentLength + ( *amplitudePtr * ( float )m_lfo->tick() ) );
m_delay->tick( buf[f] );
+9 -18
View File
@@ -57,24 +57,15 @@ StereoDelay::~StereoDelay()
void StereoDelay::tick( sampleFrame frame )
{
m_buffer[m_index][0] = frame[0];
m_buffer[m_index][1] = frame[1];
int readIndex = m_index - ( int )m_length - 1;
if( readIndex < 0 )
{
readIndex += m_maxLength;
}
float fract = 1.0f - fraction( m_length );
frame[0] = linearInterpolate( m_buffer[readIndex][0] ,
m_buffer[( readIndex+1) % m_maxLength][0], fract );
frame[1] = linearInterpolate( m_buffer[readIndex][1] ,
m_buffer[( readIndex+1) % m_maxLength][1], fract );
m_buffer[m_index][0] += frame[0] * m_feedback;
m_buffer[m_index][1] += frame[1] * m_feedback;
m_index = ( m_index + 1) % (int) m_maxLength;
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 );
frame[ 0 ] = lOut;
frame[ 1 ] = rOut;
}
+1 -1
View File
@@ -153,7 +153,7 @@ bool DualFilterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
if( ( ( *cut1Ptr != m_currentCut1 ||
*res1Ptr != m_currentRes1 ) ) || m_filter1changed )
{
m_filter1->calcFilterCoeffs( *cut1Ptr, *res2Ptr );
m_filter1->calcFilterCoeffs( *cut1Ptr, *res1Ptr );
m_filter1changed = false;
m_currentCut1 = *cut1Ptr;
m_currentRes1 = *res1Ptr;
+8 -8
View File
@@ -56,14 +56,14 @@ EqControls::EqControls( EqEffect *effect ) :
m_para4FreqModel( 4000.0, 27.0, 20000, 0.001, this , tr( "Peak 4 freq" ) ),
m_highShelfFreqModel( 12000.0, 27.0, 20000, 0.001, this , tr( "High shelf freq" ) ),
m_lpFreqModel( 18000.0, 27.0, 20000, 0.001, this , tr( "LP freq" ) ),
m_hpActiveModel( false, this , tr( "HP active" ) ),
m_lowShelfActiveModel( false, this , tr( "Low shelf active" ) ),
m_para1ActiveModel(false, this , tr( "Peak 1 active" ) ),
m_para2ActiveModel( false, this , tr( "Peak 2 active" ) ),
m_para3ActiveModel( false, this , tr( "Peak 3 active" ) ),
m_para4ActiveModel( false, this , tr( "Peak 4 active" ) ),
m_highShelfActiveModel( false, this , tr( "High shelf active" ) ),
m_lpActiveModel( false, this , tr( "LP active" ) ),
m_hpActiveModel( true, this , tr( "HP active" ) ),
m_lowShelfActiveModel( true, this , tr( "Low shelf active" ) ),
m_para1ActiveModel(true, this , tr( "Peak 1 active" ) ),
m_para2ActiveModel( true, this , tr( "Peak 2 active" ) ),
m_para3ActiveModel( true, this , tr( "Peak 3 active" ) ),
m_para4ActiveModel( true, this , tr( "Peak 4 active" ) ),
m_highShelfActiveModel( true, this , tr( "High shelf active" ) ),
m_lpActiveModel( true, this , tr( "LP active" ) ),
m_lp12Model( false, this , tr( "LP 12" ) ),
m_lp24Model( false, this , tr( "LP 24" ) ),
m_lp48Model( false, this , tr( "LP 48" ) ),
+9 -20
View File
@@ -25,6 +25,7 @@
#include "MonoDelay.h"
#include "interpolation.h"
#include "lmms_math.h"
#include "string.h"
MonoDelay::MonoDelay( int maxTime , int sampleRate )
{
@@ -51,27 +52,14 @@ MonoDelay::~MonoDelay()
void MonoDelay::tick( sample_t* sample )
{
m_buffer[m_index] = *sample;
int readIndex = m_index - ( int )m_length - 1;
if(readIndex < 0)
{
readIndex += m_maxLength;
}
float fract = 1.0f - fraction( m_length );
if(readIndex != m_maxLength-1 )
{
*sample = linearInterpolate(m_buffer[readIndex] ,
m_buffer[readIndex+1], fract );
} else
{
*sample = linearInterpolate(m_buffer[readIndex] ,
m_buffer[0], fract );
}
m_buffer[m_index] += *sample * m_feedback;
m_index = ( m_index +1 ) % m_maxLength;
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 );
*sample = out;
}
@@ -85,5 +73,6 @@ void MonoDelay::setSampleRate( int sampleRate )
}
m_buffer = new sample_t[( int )( sampleRate * m_maxTime )];
m_buffer = new sample_t[( int )( sampleRate * m_maxTime ) ];
memset( m_buffer, 0, sizeof(float) * ( int )( sampleRate * m_maxTime ) );
}
+2 -2
View File
@@ -1069,7 +1069,7 @@ void GigInstrumentView::showFileDialog()
if( QFileInfo( f ).isRelative() )
{
f = ConfigManager::inst()->userSamplesDir() + f;
f = ConfigManager::inst()->gigDir() + f;
if( QFileInfo( f ).exists() == false )
{
@@ -1082,7 +1082,7 @@ void GigInstrumentView::showFileDialog()
}
else
{
ofd.setDirectory( ConfigManager::inst()->userSamplesDir() );
ofd.setDirectory( ConfigManager::inst()->gigDir() );
}
m_fileDialogButton->setEnabled( false );
+7 -4
View File
@@ -286,11 +286,10 @@ static LADSPA_Handle instantiateMbeq(
// Create raised cosine window table
for (i=0; i < FFT_LENGTH; i++) {
window[i] = -0.5f*cos(2.0f*M_PI*(double)i/(double)FFT_LENGTH)+0.5f;
window[i] *= 2.0f;
window[i] = -0.5f * cos(2.0f*M_PI*(double)i/(double)FFT_LENGTH) + 0.5f;
}
// Create db->coeffiecnt lookup table
// Create db->coefficient lookup table
db_table = malloc(1000 * sizeof(float));
for (i=0; i < 1000; i++) {
db = ((float)i/10) - 70;
@@ -472,8 +471,12 @@ static void runMbeq(LADSPA_Handle instance, unsigned long sample_count) {
// Window into the output accumulator
for (i = 0; i < FFT_LENGTH; i++) {
out_accum[i] += 0.9186162f * window[i] * real[i]/(FFT_LENGTH * OVER_SAMP);
// correction factor for window measured from white noise
// reduce intermediate output by (number of coefficients) * OVER_SAMP
out_accum[i] += real[i] * window[i] * 1.27519f /
((FFT_LENGTH/2) * OVER_SAMP);
}
for (i = 0; i < step_size; i++) {
out_fifo[i] = out_accum[i];
}
+33 -15
View File
@@ -215,8 +215,9 @@ public:
bool isSF2;
bool hasNotes;
MidiTime lastEnd;
QString trackName;
smfMidiChannel * create( TrackContainer* tc )
smfMidiChannel * create( TrackContainer* tc, QString tn )
{
if( !it ) {
it = dynamic_cast<InstrumentTrack *>( Track::create( Track::InstrumentTrack, tc ) );
@@ -238,7 +239,10 @@ public:
#else
it_inst = it->loadInstrument( "patman" );
#endif
trackName = tn;
if( trackName != "") {
it->setName( tn );
}
lastEnd = 0;
}
return this;
@@ -353,6 +357,7 @@ bool MidiImport::readSMF( TrackContainer* tc )
// Tracks
for( int t = 0; t < seq->tracks(); ++t )
{
QString trackName = "";
Alg_track_ptr trk = seq->track( t );
pd.setValue( t + preTrackSteps );
@@ -368,15 +373,34 @@ bool MidiImport::readSMF( TrackContainer* tc )
if( evt->chan == -1 )
{
printf("MISSING GLOBAL THINGY\n");
printf(" %d %d %f %s\n", (int) evt->chan,
evt->get_type_code(), evt->time,
evt->get_attribute() );
// Global stuff
bool handled = false;
if( evt->is_update() )
{
QString attr = evt->get_attribute();
if( attr == "tracknames" && evt->get_update_type() == 'a' ) {
trackName = evt->get_atom_value();
handled = true;
}
}
if( !handled ) {
// Write debug output
printf("MISSING GLOBAL HANDLER\n");
printf(" Chn: %d, Type Code: %d, Time: %f", (int) evt->chan,
evt->get_type_code(), evt->time );
if ( evt->is_update() )
{
printf( ", Update Type: %s", evt->get_attribute() );
if ( evt->get_update_type() == 'a' )
{
printf( ", Atom: %s", evt->get_atom_value() );
}
}
printf( "\n" );
}
}
else if( evt->is_note() && evt->chan < 256 )
{
smfMidiChannel * ch = chs[evt->chan].create( tc );
smfMidiChannel * ch = chs[evt->chan].create( tc, trackName );
Alg_note_ptr noteEvt = dynamic_cast<Alg_note_ptr>( evt );
Note n( noteEvt->get_duration() * ticksPerBeat,
@@ -389,7 +413,7 @@ bool MidiImport::readSMF( TrackContainer* tc )
else if( evt->is_update() )
{
smfMidiChannel * ch = chs[evt->chan].create( tc );
smfMidiChannel * ch = chs[evt->chan].create( tc, trackName );
double time = evt->time*ticksPerBeat;
QString update( evt->get_attribute() );
@@ -415,12 +439,6 @@ bool MidiImport::readSMF( TrackContainer* tc )
}
}
}
else if( update == "tracknames" )
{
QString trackName( evt->get_string_value() );
ch->it->setName( trackName );
//ch.p->setName( trackName );
}
else if( update.startsWith( "control" ) || update == "bendr" )
{
@@ -716,7 +716,7 @@ void AudioFileProcessorView::paintEvent( QPaintEvent * )
void AudioFileProcessorView::sampleUpdated( void )
{
newWaveView();
m_waveView->updateSampleRange();
m_waveView->update();
update();
}
@@ -733,7 +733,7 @@ void AudioFileProcessorView::openAudioFile( void )
{
castModel<audioFileProcessor>()->setAudioFile( af );
Engine::getSong()->setModified();
newWaveView();
m_waveView->updateSampleRange();
}
}
@@ -759,6 +759,16 @@ void AudioFileProcessorView::modelChanged( void )
void AudioFileProcessorWaveView::updateSampleRange()
{
if( m_sampleBuffer.frames() > 1 )
{
const f_cnt_t marging = ( m_sampleBuffer.endFrame() - m_sampleBuffer.startFrame() ) * 0.1;
m_from = qMax( 0, m_sampleBuffer.startFrame() - marging );
m_to = qMin( m_sampleBuffer.endFrame() + marging, m_sampleBuffer.frames() );
}
}
AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _w, int _h, SampleBuffer& buf ) :
QWidget( _parent ),
m_sampleBuffer( buf ),
@@ -779,12 +789,7 @@ AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _
setFixedSize( _w, _h );
setMouseTracking( true );
if( m_sampleBuffer.frames() > 1 )
{
const f_cnt_t marging = ( m_sampleBuffer.endFrame() - m_sampleBuffer.startFrame() ) * 0.1;
m_from = qMax( 0, m_sampleBuffer.startFrame() - marging );
m_to = qMin( m_sampleBuffer.endFrame() + marging, m_sampleBuffer.frames() );
}
updateSampleRange();
m_graph.fill( Qt::transparent );
update();
@@ -261,6 +261,7 @@ public:
void setKnobs(knob *_start, knob *_end, knob *_loop );
void updateSampleRange();
private:
void zoom( const bool _out = false );
void slide( int _px );
+3
View File
@@ -263,6 +263,9 @@ intptr_t CarlaInstrument::handleDispatcher(const NativeHostDispatcherOpcode opco
case NATIVE_HOST_OPCODE_UI_UNAVAILABLE:
handleUiClosed();
break;
case NATIVE_HOST_OPCODE_HOST_IDLE:
qApp->processEvents();
break;
}
return ret;
+4 -3
View File
@@ -141,9 +141,6 @@ opl2instrument::opl2instrument( InstrumentTrack * _instrument_track ) :
vib_depth_mdl(false, this, tr( "Vibrato Depth" ) ),
trem_depth_mdl(false, this, tr( "Tremolo Depth" ) )
{
// Connect the plugin to the mixer...
InstrumentPlayHandle * iph = new InstrumentPlayHandle( this, _instrument_track );
Engine::mixer()->addPlayHandle( iph );
// Create an emulator - samplerate, 16 bit, mono
emulatorMutex.lock();
@@ -220,6 +217,10 @@ opl2instrument::opl2instrument( InstrumentTrack * _instrument_track ) :
MOD_CON( fm_mdl );
MOD_CON( vib_depth_mdl );
MOD_CON( trem_depth_mdl );
// Connect the plugin to the mixer...
InstrumentPlayHandle * iph = new InstrumentPlayHandle( this, _instrument_track );
Engine::mixer()->addPlayHandle( iph );
}
opl2instrument::~opl2instrument() {
+5 -6
View File
@@ -118,9 +118,6 @@ sf2Instrument::sf2Instrument( InstrumentTrack * _instrument_track ) :
// everytime we load a new soundfont.
m_synth = new_fluid_synth( m_settings );
InstrumentPlayHandle * iph = new InstrumentPlayHandle( this, _instrument_track );
Engine::mixer()->addPlayHandle( iph );
loadFile( ConfigManager::inst()->defaultSoundfont() );
updateSampleRate();
@@ -152,6 +149,8 @@ sf2Instrument::sf2Instrument( InstrumentTrack * _instrument_track ) :
connect( &m_chorusSpeed, SIGNAL( dataChanged() ), this, SLOT( updateChorus() ) );
connect( &m_chorusDepth, SIGNAL( dataChanged() ), this, SLOT( updateChorus() ) );
InstrumentPlayHandle * iph = new InstrumentPlayHandle( this, _instrument_track );
Engine::mixer()->addPlayHandle( iph );
}
@@ -928,7 +927,7 @@ sf2InstrumentView::sf2InstrumentView( Instrument * _instrument, QWidget * _paren
m_chorusButton->move( 14, 226 );
m_chorusButton->setActiveGraphic( PLUGIN_NAME::getIconPixmap( "chorus_on" ) );
m_chorusButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "chorus_off" ) );
ToolTip::add( m_reverbButton, tr( "Apply chorus (if supported)" ) );
ToolTip::add( m_chorusButton, tr( "Apply chorus (if supported)" ) );
m_chorusButton->setWhatsThis(
tr( "This button enables the chorus effect. "
"This is useful for cool echo effects, but only works on "
@@ -1068,7 +1067,7 @@ void sf2InstrumentView::showFileDialog()
QString f = k->m_filename;
if( QFileInfo( f ).isRelative() )
{
f = ConfigManager::inst()->userSamplesDir() + f;
f = ConfigManager::inst()->sf2Dir() + f;
if( QFileInfo( f ).exists() == false )
{
f = ConfigManager::inst()->factorySamplesDir() + k->m_filename;
@@ -1079,7 +1078,7 @@ void sf2InstrumentView::showFileDialog()
}
else
{
ofd.setDirectory( ConfigManager::inst()->userSamplesDir() );
ofd.setDirectory( ConfigManager::inst()->sf2Dir() );
}
m_fileDialogButton->setEnabled( false );
+8 -7
View File
@@ -133,9 +133,10 @@ void SfxrSynth::resetSample( bool restart )
env_vol=0.0f;
env_stage=0;
env_time=0;
env_length[0]=(int)(s->m_attModel.value()*s->m_attModel.value()*100000.0f);
env_length[1]=(int)(s->m_holdModel.value()*s->m_holdModel.value()*100000.0f);
env_length[2]=(int)(s->m_decModel.value()*s->m_decModel.value()*100000.0f);
env_length[0]=(int)(s->m_attModel.value()*s->m_attModel.value()*99999.0f)+1;
env_length[1]=(int)(s->m_holdModel.value()*s->m_holdModel.value()*99999.0f)+1;
env_length[2]=(int)(s->m_decModel.value()*s->m_decModel.value()*99999.0f)+1;
fphase=pow(s->m_phaserOffsetModel.value(), 2.0f)*1020.0f;
if(s->m_phaserOffsetModel.value()<0.0f) fphase=-fphase;
@@ -337,8 +338,8 @@ sfxrInstrument::sfxrInstrument( InstrumentTrack * _instrument_track ) :
m_changeAmtModel(0.0f, this, "Change Amount"),
m_changeSpeedModel(0.0f, this, "Change Speed"),
m_sqrDutyModel(0.0f, this, "Squre Duty"),
m_sqrSweepModel(0.0f, this, "Squre Sweep"),
m_sqrDutyModel(0.0f, this, "Square Duty"),
m_sqrSweepModel(0.0f, this, "Duty Sweep"),
m_repeatSpeedModel(0.0f, this, "Repeat Speed"),
@@ -633,8 +634,8 @@ sfxrInstrumentView::sfxrInstrumentView( Instrument * _instrument,
m_changeAmtKnob ->setObjectName( "changeKnob" );
m_changeSpeedKnob ->setObjectName( "changeKnob" );
createKnob(m_sqrDutyKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Squre Duty(Square wave only)");
createKnob(m_sqrSweepKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*4, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Squre Sweep(Square wave only)");
createKnob(m_sqrDutyKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*3, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Square Duty (Square wave only)");
createKnob(m_sqrSweepKnob, KNOBS_BASE_X+KNOB_BLOCK_SIZE_X*4, KNOBS_BASE_Y+KNOB_BLOCK_SIZE_Y*2, "Duty Sweep (Square wave only)");
m_sqrDutyKnob ->setObjectName( "sqrKnob" );
m_sqrSweepKnob ->setObjectName( "sqrKnob" );
+4 -4
View File
@@ -263,8 +263,8 @@ private:
Knob * m_changeAmtKnob; //Change Amount
Knob * m_changeSpeedKnob; //Change Speed
Knob * m_sqrDutyKnob; //Squre Duty
Knob * m_sqrSweepKnob; //Squre Sweep
Knob * m_sqrDutyKnob; //Square Wave Duty
Knob * m_sqrSweepKnob; //Square Wave Duty Sweep
Knob * m_repeatSpeedKnob; //Repeat Speed
@@ -278,8 +278,8 @@ private:
Knob * m_hpFilCutSweepKnob; //HP Filter Cutoff Sweep
automatableButtonGroup * m_waveBtnGroup;
PixmapButton * m_sqrWaveBtn; //NOTE: This button has Squre Duty
//and Squre Speed configurable
PixmapButton * m_sqrWaveBtn; //NOTE: This button has Square Duty
//and Square Speed configurable
PixmapButton * m_sawWaveBtn;
PixmapButton * m_sinWaveBtn;
PixmapButton * m_noiseWaveBtn;
+10
View File
@@ -335,6 +335,16 @@ malletsInstrumentView::malletsInstrumentView( malletsInstrument * _instrument,
m_spreadKnob->setLabel( tr( "Spread" ) );
m_spreadKnob->move( 190, 140 );
m_spreadKnob->setHintText( tr( "Spread:" ), "" );
// try to inform user about missing Stk-installation
if( _instrument->m_filesMissing && Engine::hasGUI() )
{
QMessageBox::information( 0, tr( "Missing files" ),
tr( "Your Stk-installation seems to be "
"incomplete. Please make sure "
"the full Stk-package is installed!" ),
QMessageBox::Ok );
}
}
+2 -1
View File
@@ -5,13 +5,14 @@ INCLUDE(BuildPlugin)
IF(LMMS_BUILD_WIN32)
ADD_DEFINITIONS(-DPTW32_STATIC_LIB)
ADD_EXECUTABLE(RemoteVstPlugin "${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp")
IF(QT5)
TARGET_LINK_LIBRARIES(RemoteVstPlugin Qt5::Core)
ELSE()
TARGET_LINK_LIBRARIES(RemoteVstPlugin -lQtCore4)
ENDIF()
TARGET_LINK_LIBRARIES(RemoteVstPlugin -lpthread -lgdi32 -lws2_32)
SET_TARGET_PROPERTIES(RemoteVstPlugin PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O3")
SET_TARGET_PROPERTIES(RemoteVstPlugin PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O0")
ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin POST_BUILD COMMAND "${STRIP}" "$<TARGET_FILE:RemoteVstPlugin>")
INSTALL(TARGETS RemoteVstPlugin RUNTIME DESTINATION "${PLUGIN_DIR}")
+1 -1
View File
@@ -5,7 +5,7 @@ ADD_EXECUTABLE(RemoteVstPlugin32 "${CMAKE_CURRENT_SOURCE_DIR}/../RemoteVstPlugin
TARGET_LINK_LIBRARIES(RemoteVstPlugin32 -lQtCore4 -lpthread -lgdi32 -lws2_32)
ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin32 POST_BUILD COMMAND "${STRIP}" "$<TARGET_FILE:RemoteVstPlugin32>")
SET_TARGET_PROPERTIES(RemoteVstPlugin32 PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O3")
SET_TARGET_PROPERTIES(RemoteVstPlugin32 PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O0")
INSTALL(TARGETS RemoteVstPlugin32 RUNTIME DESTINATION "${PLUGIN_DIR}/32")
INSTALL(FILES "${MINGW_PREFIX32}/bin/QtCore4.dll" "${MINGW_PREFIX32}/bin/zlib1.dll" "${MINGW_PREFIX32}/${CMAKE_SYSTEM_PROCESSOR32}-w64-mingw32/bin/libwinpthread-1.dll"
+1 -1
View File
@@ -147,7 +147,7 @@ ENDIF(LMMS_BUILD_WIN32)
# FLTK needs X
IF(LMMS_BUILD_LINUX)
TARGET_LINK_LIBRARIES(RemoteZynAddSubFx -ldl)
TARGET_LINK_LIBRARIES(RemoteZynAddSubFx ${CMAKE_DL_LIBS})
ENDIF(LMMS_BUILD_LINUX)
+4 -2
View File
@@ -350,14 +350,16 @@ bool ZynAddSubFxInstrument::handleMidiEvent( const MidiEvent& event, const MidiT
return true;
}
MidiEvent localEvent = event;
localEvent.setChannel( 0 );
m_pluginMutex.lock();
if( m_remotePlugin )
{
m_remotePlugin->processMidiEvent( event, 0 );
m_remotePlugin->processMidiEvent( localEvent, 0 );
}
else
{
m_plugin->processMidiEvent( event );
m_plugin->processMidiEvent( localEvent );
}
m_pluginMutex.unlock();
+4 -6
View File
@@ -31,7 +31,6 @@
#include "ProjectJournal.h"
#include "BBTrackContainer.h"
#include "Song.h"
#include "TextFloat.h"
#include "embed.h"
int AutomationPattern::s_quantization = 1;
@@ -107,7 +106,7 @@ AutomationPattern::~AutomationPattern()
void AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
bool AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
{
if( _search_dup )
{
@@ -115,10 +114,8 @@ void AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
it != m_objects.end(); ++it )
{
if( *it == _obj )
{
TextFloat::displayMessage( _obj->displayName(), tr( "Model is already connected "
"to this pattern." ), embed::getIconPixmap( "automation" ), 2000 );
return;
{
return false;
}
}
}
@@ -138,6 +135,7 @@ void AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
emit dataChanged();
return true;
}
+27 -28
View File
@@ -61,6 +61,8 @@ ConfigManager::ConfigManager() :
m_artworkDir( defaultArtworkDir() ),
m_vstDir( m_workingDir + "vst" + QDir::separator() ),
m_flDir( QDir::home().absolutePath() ),
m_gigDir( m_workingDir + GIG_PATH ),
m_sf2Dir( m_workingDir + SF2_PATH ),
m_version( defaultVersion() )
{
if (! qgetenv("LMMS_DATA_DIR").isEmpty())
@@ -176,6 +178,16 @@ void ConfigManager::setBackgroundArtwork( const QString & _ba )
#endif
}
void ConfigManager::setGIGDir(const QString &gd)
{
m_gigDir = gd;
}
void ConfigManager::setSF2Dir(const QString &sfd)
{
m_sf2Dir = sfd;
}
@@ -237,31 +249,6 @@ void ConfigManager::setValue( const QString & _class,
#ifdef LMMS_BUILD_WIN32
#include <QLibrary>
#include <shlobj.h>
// taken from qt-win-opensource-src-4.2.2/src/corelib/io/qsettings.cpp
static QString windowsConfigPath( int _type )
{
QString result;
QLibrary library( "shell32" );
typedef BOOL( WINAPI* GetSpecialFolderPath )( HWND, char *, int, BOOL );
GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)
library.resolve( "SHGetSpecialFolderPathA" );
if( SHGetSpecialFolderPath )
{
char path[MAX_PATH];
SHGetSpecialFolderPath( 0, path, _type, false );
result = QString::fromLocal8Bit( path );
}
return result;
}
#endif
void ConfigManager::loadConfigFile()
{
// read the XML file and create DOM tree
@@ -336,6 +323,9 @@ void ConfigManager::loadConfigFile()
}
}
setWorkingDir( value( "paths", "workingdir" ) );
setGIGDir( value( "paths", "gigdir" ) == "" ? gigDir() : value( "paths", "gigdir" ) );
setSF2Dir( value( "paths", "sf2dir" ) == "" ? sf2Dir() : value( "paths", "sf2dir" ) );
setVSTDir( value( "paths", "vstdir" ) );
setFLDir( value( "paths", "fldir" ) );
setLADSPADir( value( "paths", "laddir" ) );
@@ -363,10 +353,10 @@ void ConfigManager::loadConfigFile()
!QDir( m_vstDir ).exists() )
{
#ifdef LMMS_BUILD_WIN32
m_vstDir = windowsConfigPath( CSIDL_PROGRAM_FILES ) +
QDir::separator() + "VstPlugins";
QString programFiles = QString::fromLocal8Bit( getenv( "ProgramFiles" ) );
m_vstDir = programFiles + QDir::separator() + "VstPlugins" + QDir::separator();
#else
m_vstDir = ensureTrailingSlash( QDir::home().absolutePath() );
m_vstDir = m_workingDir + "plugins/vst/";
#endif
}
@@ -385,6 +375,7 @@ void ConfigManager::loadConfigFile()
#else
m_ladDir = qApp->applicationDirPath() + '/' + LIB_DIR + "/ladspa/";
#endif
m_ladDir += ","+userLadspaDir();
}
#ifdef LMMS_HAVE_STK
@@ -422,8 +413,14 @@ void ConfigManager::loadConfigFile()
if( QDir( m_workingDir ).exists() )
{
QDir().mkpath( userProjectsDir() );
QDir().mkpath( userTemplateDir() );
QDir().mkpath( userSamplesDir() );
QDir().mkpath( userPresetsDir() );
QDir().mkpath( userGigDir() );
QDir().mkpath( userSf2Dir() );
QDir().mkpath( userVstDir() );
QDir().mkpath( userLadspaDir() );
}
upgrade();
@@ -438,6 +435,8 @@ void ConfigManager::saveConfigFile()
setValue( "paths", "workingdir", m_workingDir );
setValue( "paths", "vstdir", m_vstDir );
setValue( "paths", "fldir", m_flDir );
setValue( "paths", "gigdir", m_gigDir );
setValue( "paths", "sf2dir", m_sf2Dir );
setValue( "paths", "laddir", m_ladDir );
#ifdef LMMS_HAVE_STK
setValue( "paths", "stkdir", m_stkDir );
+8
View File
@@ -52,9 +52,13 @@ DummyTrackContainer * Engine::s_dummyTC = NULL;
void Engine::init()
{
Engine *engine = inst();
emit engine->initProgress(tr("Generating wavetables"));
// generate (load from file) bandlimited wavetables
BandLimitedWave::generateWaves();
emit engine->initProgress(tr("Initializing data structures"));
s_projectJournal = new ProjectJournal;
s_mixer = new Mixer;
s_song = new Song;
@@ -65,11 +69,13 @@ void Engine::init()
s_projectJournal->setJournalling( true );
emit engine->initProgress(tr("Opening audio and midi devices"));
s_mixer->initDevices();
PresetPreviewPlayHandle::init();
s_dummyTC = new DummyTrackContainer;
emit engine->initProgress(tr("Launching mixer threads"));
s_mixer->startProcessing();
}
@@ -114,3 +120,5 @@ void Engine::updateFramesPerTick()
s_framesPerTick = s_mixer->processingSampleRate() * 60.0f * 4 /
DefaultTicksPerTact / s_song->getTempo();
}
Engine * Engine::s_instanceOfMe = NULL;
+17 -26
View File
@@ -98,8 +98,8 @@ inline void FxChannel::processed()
void FxChannel::incrementDeps()
{
m_dependenciesMet.ref();
if( m_dependenciesMet >= m_receives.size() && ! m_queued )
int i = m_dependenciesMet.fetchAndAddOrdered( 1 ) + 1;
if( i >= m_receives.size() && ! m_queued )
{
m_queued = true;
MixerWorkerThread::addJob( this );
@@ -327,6 +327,19 @@ void FxMixer::deleteChannel( int index )
for( int i = index; i < m_fxChannels.size(); ++i )
{
validateChannelName( i, i + 1 );
// set correct channel index
m_fxChannels[i]->m_channelIndex = i;
// now check all routes and update names of the send models
foreach( FxRoute * r, m_fxChannels[i]->m_sends )
{
r->updateName();
}
foreach( FxRoute * r, m_fxChannels[i]->m_receives )
{
r->updateName();
}
}
}
@@ -364,18 +377,9 @@ void FxMixer::moveChannelLeft( int index )
{
inst->effectChannelModel()->setValue(a);
}
}
}
}
// actually do the swap
FxChannel * tmpChannel = m_fxChannels[a];
m_fxChannels[a] = m_fxChannels[b];
m_fxChannels[b] = tmpChannel;
validateChannelName( a, b );
validateChannelName( b, a );
}
@@ -761,22 +765,9 @@ void FxMixer::loadSettings( const QDomElement & _this )
void FxMixer::validateChannelName( int index, int oldIndex )
{
FxChannel * fxc = m_fxChannels[ index ];
if( fxc->m_name == tr( "FX %1" ).arg( oldIndex ) )
if( m_fxChannels[index]->m_name == tr( "FX %1" ).arg( oldIndex ) )
{
fxc->m_name = tr( "FX %1" ).arg( index );
}
// set correct channel index
fxc->m_channelIndex = index;
// now check all routes and update names of the send models
foreach( FxRoute * r, fxc->m_sends )
{
r->updateName();
}
foreach( FxRoute * r, fxc->m_receives )
{
r->updateName();
m_fxChannels[index]->m_name = tr( "FX %1" ).arg( index );
}
}
+1 -2
View File
@@ -28,8 +28,7 @@
InstrumentPlayHandle::InstrumentPlayHandle( Instrument * instrument, InstrumentTrack* instrumentTrack ) :
PlayHandle( TypeInstrumentPlayHandle ),
m_instrument( instrument ),
m_instrumentTrack( instrumentTrack )
m_instrument( instrument )
{
setAudioPort( instrumentTrack->audioPort() );
}
+1 -9
View File
@@ -930,15 +930,7 @@ void Mixer::fifoWriter::finish()
void Mixer::fifoWriter::run()
{
// set denormal protection for this thread
#ifdef __SSE3__
/* DAZ flag */
_MM_SET_DENORMALS_ZERO_MODE( _MM_DENORMALS_ZERO_ON );
#endif
#ifdef __SSE__
/* FTZ flag */
_MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
#endif
disable_denormals();
#if 0
#ifdef LMMS_BUILD_LINUX
+3 -15
View File
@@ -29,12 +29,7 @@
#include "ThreadableJob.h"
#include "Mixer.h"
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#ifdef __SSE3__
#include <pmmintrin.h>
#endif
#include "denormals.h"
MixerWorkerThread::JobQueue MixerWorkerThread::globalJobQueue;
QWaitCondition * MixerWorkerThread::queueReadyWaitCond = NULL;
@@ -159,15 +154,8 @@ void MixerWorkerThread::startAndWaitForJobs()
void MixerWorkerThread::run()
{
// set denormal protection for this thread
#ifdef __SSE3__
/* DAZ flag */
_MM_SET_DENORMALS_ZERO_MODE( _MM_DENORMALS_ZERO_ON );
#endif
#ifdef __SSE__
/* FTZ flag */
_MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
#endif
disable_denormals();
QMutex m;
while( m_quit == false )
{
+9
View File
@@ -97,6 +97,15 @@ void ProjectJournal::redo()
}
}
bool ProjectJournal::canUndo() const
{
return !m_undoCheckPoints.isEmpty();
}
bool ProjectJournal::canRedo() const
{
return !m_redoCheckPoints.isEmpty();
}
+35 -51
View File
@@ -94,7 +94,6 @@ Song::Song() :
m_errors( new QList<QString>() ),
m_playMode( Mode_None ),
m_length( 0 ),
m_trackToPlay( NULL ),
m_patternToPlay( NULL ),
m_loopPattern( false ),
m_elapsedMilliSeconds( 0 ),
@@ -199,14 +198,17 @@ void Song::savePos()
void Song::processNextBuffer()
{
// if not playing, nothing to do
if( m_playing == false )
{
return;
}
TrackList trackList;
int tcoNum = -1;
int tcoNum = -1; // track content object number
// determine the list of tracks to play and the track content object
// (TCO) number
switch( m_playMode )
{
case Mode_PlaySong:
@@ -218,10 +220,6 @@ void Song::processNextBuffer()
}
break;
case Mode_PlayTrack:
trackList.push_back( m_trackToPlay );
break;
case Mode_PlayBB:
if( Engine::getBBTrackContainer()->numOfBBs() > 0 )
{
@@ -247,6 +245,7 @@ void Song::processNextBuffer()
}
// if we have no tracks to play, nothing to do
if( trackList.empty() == true )
{
return;
@@ -259,6 +258,8 @@ void Song::processNextBuffer()
if( checkLoop )
{
// if looping-mode is enabled and we are outside of the looping
// range, go to the beginning of the range
if( m_playPos[m_playMode] < tl->loopBegin() ||
m_playPos[m_playMode] >= tl->loopEnd() )
{
@@ -269,16 +270,13 @@ void Song::processNextBuffer()
}
}
f_cnt_t totalFramesPlayed = 0;
f_cnt_t framesPlayed = 0;
const float framesPerTick = Engine::framesPerTick();
while( totalFramesPlayed < Engine::mixer()->framesPerPeriod() )
while( framesPlayed < Engine::mixer()->framesPerPeriod() )
{
m_vstSyncController.update();
f_cnt_t playedFrames = Engine::mixer()->framesPerPeriod() -
totalFramesPlayed;
float currentFrame = m_playPos[m_playMode].currentFrame();
// did we play a tick?
if( currentFrame >= framesPerTick )
@@ -335,6 +333,9 @@ void Song::processNextBuffer()
m_vstSyncController.startCycle(
tl->loopBegin().getTicks(), tl->loopEnd().getTicks() );
// if looping-mode is enabled and we have got
// past the looping range, return to the
// beginning of the range
if( m_playPos[m_playMode] >= tl->loopEnd() )
{
m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() );
@@ -353,23 +354,26 @@ void Song::processNextBuffer()
m_playPos[m_playMode].setCurrentFrame( currentFrame );
}
f_cnt_t lastFrames = ( f_cnt_t )framesPerTick -
( f_cnt_t )currentFrame;
f_cnt_t framesToPlay =
Engine::mixer()->framesPerPeriod() - framesPlayed;
f_cnt_t framesLeft = ( f_cnt_t )framesPerTick -
( f_cnt_t )currentFrame;
// skip last frame fraction
if( lastFrames == 0 )
if( framesLeft == 0 )
{
++totalFramesPlayed;
++framesPlayed;
m_playPos[m_playMode].setCurrentFrame( currentFrame
+ 1.0f );
continue;
}
// do we have some samples left in this tick but these are
// less then samples we have to play?
if( lastFrames < playedFrames )
// do we have samples left in this tick but these are less
// than samples we have to play?
if( framesLeft < framesToPlay )
{
// then set played_samples to remaining samples, the
// then set framesToPlay to remaining samples, the
// rest will be played in next loop
playedFrames = lastFrames;
framesToPlay = framesLeft;
}
if( ( f_cnt_t ) currentFrame == 0 )
@@ -378,25 +382,25 @@ void Song::processNextBuffer()
{
m_globalAutomationTrack->play(
m_playPos[m_playMode],
playedFrames,
totalFramesPlayed, tcoNum );
framesToPlay,
framesPlayed, tcoNum );
}
// loop through all tracks and play them
for( int i = 0; i < trackList.size(); ++i )
{
trackList[i]->play( m_playPos[m_playMode],
playedFrames,
totalFramesPlayed, tcoNum );
framesToPlay,
framesPlayed, tcoNum );
}
}
// update frame-counters
totalFramesPlayed += playedFrames;
m_playPos[m_playMode].setCurrentFrame( playedFrames +
framesPlayed += framesToPlay;
m_playPos[m_playMode].setCurrentFrame( framesToPlay +
currentFrame );
m_elapsedMilliSeconds +=
( ( playedFrames / framesPerTick ) * 60 * 1000 / 48 )
( ( framesToPlay / framesPerTick ) * 60 * 1000 / 48 )
/ getTempo();
m_elapsedTacts = m_playPos[Mode_PlaySong].getTact();
m_elapsedTicks = ( m_playPos[Mode_PlaySong].getTicks() % ticksPerTact() ) / 48;
@@ -470,28 +474,6 @@ void Song::playAndRecord()
void Song::playTrack( Track * trackToPlay )
{
if( isStopped() == false )
{
stop();
}
m_trackToPlay = trackToPlay;
m_playMode = Mode_PlayTrack;
m_playing = true;
m_paused = false;
m_vstSyncController.setPlaybackState( true );
savePos();
emit playbackStateChanged();
}
void Song::playBB()
{
if( isStopped() == false )
@@ -847,8 +829,10 @@ void Song::clearProject()
// create new file
void Song::createNewProject()
{
QString defaultTemplate = ConfigManager::inst()->userProjectsDir()
+ "templates/default.mpt";
QString defaultTemplate = ConfigManager::inst()->userTemplateDir()
+ "default.mpt";
if( QFile::exists( defaultTemplate ) )
{
+11 -11
View File
@@ -78,11 +78,6 @@
*/
const int RESIZE_GRIP_WIDTH = 4;
/*! The size of the track buttons in pixels
*/
const int TRACK_OP_BTN_WIDTH = 20;
const int TRACK_OP_BTN_HEIGHT = 14;
/*! A pointer for that text bubble used when moving segments, etc.
*
@@ -108,7 +103,7 @@ TrackContentObject::TrackContentObject( Track * track ) :
m_name( QString::null ),
m_startPosition(),
m_length(),
m_mutedModel( false, this, tr( "Muted" ) ),
m_mutedModel( false, this, tr( "Mute" ) ),
m_selectViewOnCreate( false )
{
if( getTrack() )
@@ -1688,13 +1683,18 @@ void TrackOperationsWidget::paintEvent( QPaintEvent * pe )
/*! \brief Clone this track
*
*/
void TrackOperationsWidget::cloneTrack()
{
m_trackView->getTrack()->clone();
TrackContainerView *tcView = m_trackView->trackContainerView();
Track *newTrack = m_trackView->getTrack()->clone();
TrackView *newTrackView = tcView->createTrackView( newTrack );
int index = tcView->trackViews().indexOf( m_trackView );
tcView->moveTrackView( newTrackView, index + 1 );
}
@@ -1810,7 +1810,7 @@ Track::Track( TrackTypes type, TrackContainer * tc ) :
m_trackContainer( tc ), /*!< The track container object */
m_type( type ), /*!< The track type */
m_name(), /*!< The track's name */
m_mutedModel( false, this, tr( "Muted" ) ),
m_mutedModel( false, this, tr( "Mute" ) ),
/*!< For controlling track muting */
m_soloModel( false, this, tr( "Solo" ) ),
/*!< For controlling track soloing */
@@ -1904,12 +1904,12 @@ Track * Track::create( const QDomElement & element, TrackContainer * tc )
/*! \brief Clone a track from this track
*
*/
void Track::clone()
Track * Track::clone()
{
QDomDocument doc;
QDomElement parent = doc.createElement( "clone" );
saveState( doc, parent );
create( parent.firstChild().toElement(), m_trackContainer );
return create( parent.firstChild().toElement(), m_trackContainer );
}
+10 -26
View File
@@ -27,13 +27,7 @@
#include "lmmsversion.h"
#include "versioninfo.h"
// denormals stripping
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#ifdef __SSE3__
#include <pmmintrin.h>
#endif
#include "denormals.h"
#include <QFileInfo>
#include <QLocale>
@@ -103,15 +97,7 @@ int main( int argc, char * * argv )
// intialize RNG
srand( getpid() + time( 0 ) );
// set denormal protection for this thread
#ifdef __SSE3__
/* DAZ flag */
_MM_SET_DENORMALS_ZERO_MODE( _MM_DENORMALS_ZERO_ON );
#endif
#ifdef __SSE__
/* FTZ flag */
_MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
#endif
disable_denormals();
bool core_only = false;
bool fullscreen = true;
@@ -217,12 +203,10 @@ int main( int argc, char * * argv )
else if( argc > i+1 && ( QString( argv[i] ) == "--upgrade" ||
QString( argv[i] ) == "-u" ) )
{
QString inFile( argv[i + 1] );
DataFile dataFile( inFile );
DataFile dataFile( QString::fromLocal8Bit( argv[i + 1] ) );
if (argc > i+2)
{
const QString outFile = argv[i + 2];
dataFile.writeFile( outFile );
dataFile.writeFile( QString::fromLocal8Bit( argv[i + 2] ) );
}
else
{
@@ -246,7 +230,7 @@ int main( int argc, char * * argv )
else if( argc > i && ( QString( argv[i] ) == "--dump" ||
QString( argv[i] ) == "-d" ) )
{
QFile f( argv[i + 1] );
QFile f( QString::fromLocal8Bit( argv[i + 1] ) );
f.open( QIODevice::ReadOnly );
QString d = qUncompress( f.readAll() );
printf( "%s\n", d.toUtf8().constData() );
@@ -255,14 +239,14 @@ int main( int argc, char * * argv )
else if( argc > i && ( QString( argv[i] ) == "--render" ||
QString( argv[i] ) == "-r" ) )
{
file_to_load = QString( argv[i + 1] );
file_to_load = QString::fromLocal8Bit( argv[i + 1] );
render_out = baseName( file_to_load ) + ".";
++i;
}
else if( argc > i && ( QString( argv[i] ) == "--output" ||
QString( argv[i] ) == "-o" ) )
{
render_out = baseName( QString( argv[i + 1] ) ) + ".";
render_out = baseName( QString::fromLocal8Bit( argv[i + 1] ) ) + ".";
++i;
}
else if( argc > i &&
@@ -386,7 +370,7 @@ int main( int argc, char * * argv )
else if( argc > i &&
( QString( argv[i] ) == "--import" ) )
{
file_to_import = argv[i+1];
file_to_import = QString::fromLocal8Bit( argv[i+1] );
++i;
// exit after import? (only for debugging)
if( argc > i && QString( argv[i+1] ) == "-e" )
@@ -396,7 +380,7 @@ int main( int argc, char * * argv )
}
else if( argc > i && ( QString( argv[i] ) == "--profile" || QString( argv[i] ) == "-p" ) )
{
profilerOutputFile = argv[i+1];
profilerOutputFile = QString::fromLocal8Bit( argv[i+1] );
++i;
}
else
@@ -407,7 +391,7 @@ int main( int argc, char * * argv )
"Try \"%s --help\" for more information.\n\n", argv[i], argv[0] );
return( EXIT_FAILURE );
}
file_to_load = argv[i];
file_to_load = QString::fromLocal8Bit( argv[i] );
}
}
+10 -1
View File
@@ -35,6 +35,7 @@
#include "ProjectJournal.h"
#include "RenameDialog.h"
#include "StringPairDrag.h"
#include "TextFloat.h"
#include "ToolTip.h"
@@ -420,7 +421,15 @@ void AutomationPatternView::dropEvent( QDropEvent * _de )
journallingObject( val.toInt() ) );
if( mod != NULL )
{
m_pat->addObject( mod );
bool added = m_pat->addObject( mod );
if ( !added )
{
TextFloat::displayMessage( mod->displayName(),
tr( "Model is already connected "
"to this pattern." ),
embed::getIconPixmap( "automation" ),
2000 );
}
}
update();
+1
View File
@@ -55,6 +55,7 @@ SET(LMMS_SRCS
gui/widgets/InstrumentFunctionViews.cpp
gui/widgets/InstrumentMidiIOView.cpp
gui/widgets/InstrumentSoundShapingView.cpp
gui/widgets/LeftRightNav.cpp
gui/widgets/Knob.cpp
gui/widgets/LadspaControlView.cpp
gui/widgets/LcdSpinBox.cpp
+56 -15
View File
@@ -30,6 +30,8 @@
#include "embed.h"
#include "PluginFactory.h"
#include <QLabel>
EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
QDialog( _parent ),
@@ -168,25 +170,64 @@ void EffectSelectDialog::rowChanged( const QModelIndex & _idx,
{
m_currentSelection = m_effectKeys[m_model.mapToSource( _idx ).row()];
}
if( m_currentSelection.desc && m_currentSelection.desc->subPluginFeatures )
if( m_currentSelection.desc )
{
m_descriptionWidget = new QWidget;
QVBoxLayout * l = new QVBoxLayout( m_descriptionWidget );
l->setMargin( 4 );
l->setSpacing( 0 );
ui->scrollArea->setWidget( m_descriptionWidget );
QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget );
m_currentSelection.desc->subPluginFeatures->
fillDescriptionWidget( m_descriptionWidget, &m_currentSelection );
foreach( QWidget * w, m_descriptionWidget->findChildren<QWidget *>() )
{
if( w->parent() == m_descriptionWidget )
{
l->addWidget( w );
}
}
l->setSizeConstraint( QLayout::SetFixedSize );
Plugin::Descriptor const & descriptor = *( m_currentSelection.desc );
if ( descriptor.logo )
{
QLabel *logoLabel = new QLabel( m_descriptionWidget );
logoLabel->setPixmap( descriptor.logo->pixmap() );
logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
hbox->addWidget( logoLabel );
hbox->setAlignment( logoLabel, Qt::AlignTop);
}
QWidget *textualInfoWidget = new QWidget( m_descriptionWidget );
hbox->addWidget(textualInfoWidget);
QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget);
textWidgetLayout->setMargin( 4 );
textWidgetLayout->setSpacing( 0 );
std::string stdName(descriptor.name);
if ( stdName != "ladspaeffect" )
{
QLabel *label = new QLabel(m_descriptionWidget);
QString labelText = "<p><b>" + tr("Name") + ":</b> " + QString::fromUtf8(descriptor.displayName) + "</p>";
labelText += "<p><b>" + tr("Description") + ":</b> " + QString::fromUtf8(descriptor.description) + "</p>";
labelText += "<p><b>" + tr("Author") + ":</b> " + QString::fromUtf8(descriptor.author) + "</p>";
label->setText(labelText);
textWidgetLayout->addWidget(label);
}
if ( m_currentSelection.desc->subPluginFeatures )
{
QWidget *subWidget = new QWidget(textualInfoWidget);
QVBoxLayout * subLayout = new QVBoxLayout( subWidget );
subLayout->setMargin( 4 );
subLayout->setSpacing( 0 );
m_currentSelection.desc->subPluginFeatures->
fillDescriptionWidget( subWidget, &m_currentSelection );
foreach( QWidget * w, subWidget->findChildren<QWidget *>() )
{
if( w->parent() == subWidget )
{
subLayout->addWidget( w );
}
}
textWidgetLayout->addWidget(subWidget);
}
ui->scrollArea->setWidget( m_descriptionWidget );
m_descriptionWidget->show();
}
}
+14 -3
View File
@@ -32,6 +32,7 @@
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QMessageBox>
#include <QShortcut>
#include "FileBrowser.h"
#include "BBTrackContainer.h"
@@ -98,6 +99,10 @@ FileBrowser::FileBrowser(const QString & directories, const QString & filter,
addContentWidget( ops );
// Whenever the FileBrowser has focus, Ctrl+F should direct focus to its filter box.
QShortcut *filterFocusShortcut = new QShortcut( QKeySequence( QKeySequence::Find ), this, SLOT(giveFocusToFilter()) );
filterFocusShortcut->setContext(Qt::WidgetWithChildrenShortcut);
reloadTree();
show();
}
@@ -254,7 +259,15 @@ void FileBrowser::reloadTree( void )
filterItems( text );
}
void FileBrowser::giveFocusToFilter()
{
if (!m_filterEdit->hasFocus())
{
// give focus to filter text box and highlight its text for quick editing if not previously focused
m_filterEdit->setFocus();
m_filterEdit->selectAll();
}
}
void FileBrowser::addItems(const QString & path )
@@ -872,8 +885,6 @@ bool Directory::addItems(const QString & path )
addChild( new Directory( cur_file, path,
m_filter ) );
m_dirCount++;
//recurse for each dir
addItems( path + cur_file + QDir::separator() );
}
added_something = true;
+14 -35
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>585</width>
<height>547</height>
<height>550</height>
</rect>
</property>
<property name="windowTitle">
@@ -40,41 +40,20 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>210</height>
</size>
</property>
<property name="title">
<string>Plugin description</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>497</width>
<height>109</height>
</rect>
</property>
</widget>
</widget>
</item>
</layout>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>497</width>
<height>109</height>
</rect>
</property>
</widget>
</widget>
</item>
<item>
+45 -41
View File
@@ -267,19 +267,20 @@ void FxMixerView::loadSettings( const QDomElement & _this )
FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv,
int _chIndex )
int channelIndex )
{
m_fxLine = new FxLine(_parent, _mv, _chIndex);
m_fxLine = new FxLine(_parent, _mv, channelIndex);
FxMixer * m = Engine::fxMixer();
m_fader = new Fader( &m->effectChannel(_chIndex)->m_volumeModel,
tr( "FX Fader %1" ).arg( _chIndex ), m_fxLine );
FxChannel *fxChannel = Engine::fxMixer()->effectChannel(channelIndex);
m_fader = new Fader( &fxChannel->m_volumeModel,
tr( "FX Fader %1" ).arg( channelIndex ), m_fxLine );
m_fader->move( 16-m_fader->width()/2,
m_fxLine->height()-
m_fader->height()-5 );
m_muteBtn = new PixmapButton( m_fxLine, tr( "Mute" ) );
m_muteBtn->setModel( &m->effectChannel(_chIndex)->m_muteModel );
m_muteBtn->setModel( &fxChannel->m_muteModel );
m_muteBtn->setActiveGraphic(
embed::getIconPixmap( "led_off" ) );
m_muteBtn->setInactiveGraphic(
@@ -289,23 +290,34 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv,
ToolTip::add( m_muteBtn, tr( "Mute this FX channel" ) );
m_soloBtn = new PixmapButton( m_fxLine, tr( "Solo" ) );
m_soloBtn->setModel( &m->effectChannel(_chIndex)->m_soloModel );
m_soloBtn->setModel( &fxChannel->m_soloModel );
m_soloBtn->setActiveGraphic(
embed::getIconPixmap( "led_red" ) );
m_soloBtn->setInactiveGraphic(
embed::getIconPixmap( "led_off" ) );
m_soloBtn->setCheckable( true );
m_soloBtn->move( 9, m_fader->y()-21);
connect(&m->effectChannel(_chIndex)->m_soloModel, SIGNAL( dataChanged() ),
connect(&fxChannel->m_soloModel, SIGNAL( dataChanged() ),
_mv, SLOT ( toggledSolo() ) );
ToolTip::add( m_soloBtn, tr( "Solo FX channel" ) );
// Create EffectRack for the channel
m_rackView = new EffectRackView( &m->effectChannel(_chIndex)->m_fxChain, _mv->m_racksWidget );
m_rackView = new EffectRackView( &fxChannel->m_fxChain, _mv->m_racksWidget );
m_rackView->setFixedSize( 245, FxLine::FxLineHeight );
}
void FxMixerView::FxChannelView::setChannelIndex( int index )
{
FxChannel* fxChannel = Engine::fxMixer()->effectChannel( index );
m_fader->setModel( &fxChannel->m_volumeModel );
m_muteBtn->setModel( &fxChannel->m_muteModel );
m_soloBtn->setModel( &fxChannel->m_soloModel );
m_rackView->setModel( &fxChannel->m_fxChain );
}
void FxMixerView::toggledSolo()
{
Engine::fxMixer()->toggledSolo();
@@ -432,53 +444,39 @@ void FxMixerView::deleteUnusedChannels()
void FxMixerView::moveChannelLeft(int index)
void FxMixerView::moveChannelLeft(int index, int focusIndex)
{
// can't move master or first channel left or last channel right
if( index <= 1 || index >= m_fxChannelViews.size() ) return;
int selIndex = m_currentFxLine->channelIndex();
FxMixer *m = Engine::fxMixer();
FxMixer * mix = Engine::fxMixer();
mix->moveChannelLeft(index);
// Move instruments channels
m->moveChannelLeft( index );
// refresh the two mixer views
for( int i = index-1; i <= index; ++i )
{
// delete the mixer view
int replaceIndex = chLayout->indexOf(m_fxChannelViews[i]->m_fxLine);
// Update widgets models
m_fxChannelViews[index]->setChannelIndex( index - 1 );
m_fxChannelViews[index - 1]->setChannelIndex( index );
chLayout->removeWidget(m_fxChannelViews[i]->m_fxLine);
m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView );
delete m_fxChannelViews[i]->m_fader;
delete m_fxChannelViews[i]->m_muteBtn;
delete m_fxChannelViews[i]->m_soloBtn;
delete m_fxChannelViews[i]->m_fxLine;
delete m_fxChannelViews[i];
// Swap positions in array
qSwap(m->m_fxChannels[index], m->m_fxChannels[index - 1]);
// add it again
m_fxChannelViews[i] = new FxChannelView( m_channelAreaWidget, this, i );
chLayout->insertWidget( replaceIndex, m_fxChannelViews[i]->m_fxLine );
m_racksLayout->insertWidget( replaceIndex, m_fxChannelViews[i]->m_rackView );
}
// Focus on new position
setCurrentFxLine( focusIndex );
}
// keep selected channel
if( selIndex == index )
{
selIndex = index-1;
}
else if( selIndex == index - 1 )
{
selIndex = index;
}
setCurrentFxLine(selIndex);
void FxMixerView::moveChannelLeft(int index)
{
moveChannelLeft( index, index - 1 );
}
void FxMixerView::moveChannelRight(int index)
{
moveChannelLeft(index+1);
moveChannelLeft( index + 1, index + 1 );
}
@@ -512,6 +510,12 @@ void FxMixerView::keyPressEvent(QKeyEvent * e)
setCurrentFxLine( m_currentFxLine->channelIndex()+1 );
}
break;
case Qt::Key_Insert:
if ( e->modifiers() & Qt::ShiftModifier )
{
addNewChannel();
}
break;
}
}
+48 -3
View File
@@ -49,6 +49,7 @@ GuiApplication* GuiApplication::instance()
return s_instance;
}
GuiApplication::GuiApplication()
{
// Init style and palette
@@ -64,27 +65,60 @@ GuiApplication::GuiApplication()
// Show splash screen
QSplashScreen splashScreen( embed::getIconPixmap( "splash" ) );
splashScreen.show();
splashScreen.showMessage( MainWindow::tr( "Version %1" ).arg( LMMS_VERSION ),
Qt::AlignRight | Qt::AlignBottom, Qt::white );
QHBoxLayout layout;
layout.setAlignment(Qt::AlignBottom);
splashScreen.setLayout(&layout);
// Create a left-aligned label for loading progress
// & a right-aligned label for version info
QLabel loadingProgressLabel;
m_loadingProgressLabel = &loadingProgressLabel;
QLabel versionLabel(MainWindow::tr( "Version %1" ).arg( LMMS_VERSION ));
loadingProgressLabel.setAlignment(Qt::AlignLeft);
versionLabel.setAlignment(Qt::AlignRight);
layout.addWidget(&loadingProgressLabel);
layout.addWidget(&versionLabel);
// may have long gaps between future frames, so force update now
splashScreen.update();
qApp->processEvents();
connect(Engine::inst(), SIGNAL(initProgress(const QString&)),
this, SLOT(displayInitProgress(const QString&)));
// Init central engine which handles all components of LMMS
Engine::init();
s_instance = this;
m_mainWindow = new MainWindow;
displayInitProgress(tr("Preparing UI"));
m_mainWindow = new MainWindow;
connect(m_mainWindow, SIGNAL(initProgress(const QString&)),
this, SLOT(displayInitProgress(const QString&)));
displayInitProgress(tr("Preparing song editor"));
m_songEditor = new SongEditorWindow(Engine::getSong());
displayInitProgress(tr("Preparing mixer"));
m_fxMixerView = new FxMixerView;
displayInitProgress(tr("Preparing controller rack"));
m_controllerRackView = new ControllerRackView;
displayInitProgress(tr("Preparing project notes"));
m_projectNotes = new ProjectNotes;
displayInitProgress(tr("Preparing beat/bassline editor"));
m_bbEditor = new BBEditor(Engine::getBBTrackContainer());
displayInitProgress(tr("Preparing piano roll"));
m_pianoRoll = new PianoRollWindow();
displayInitProgress(tr("Preparing automation editor"));
m_automationEditor = new AutomationEditorWindow;
m_mainWindow->finalize();
splashScreen.finish(m_mainWindow);
m_loadingProgressLabel = nullptr;
}
GuiApplication::~GuiApplication()
@@ -92,3 +126,14 @@ GuiApplication::~GuiApplication()
InstrumentTrackView::cleanupWindowCache();
s_instance = nullptr;
}
void GuiApplication::displayInitProgress(const QString &msg)
{
Q_ASSERT(m_loadingProgressLabel != nullptr);
m_loadingProgressLabel->setText(msg);
// must force a UI update and process events, as there may be long gaps between processEvents() calls during init
m_loadingProgressLabel->repaint();
qApp->processEvents();
}
-9
View File
@@ -50,7 +50,6 @@ const int CD_KNOB_X_SPACING = 32;
const int CD_LFO_SHAPES_X = 6;
const int CD_LFO_SHAPES_Y = 36;
const int CD_LFO_GRAPH_X = 6;
const int CD_LFO_GRAPH_Y = CD_ENV_KNOBS_LBL_Y+15;
const int CD_LFO_CD_KNOB_Y = CD_LFO_GRAPH_Y-2;
const int CD_LFO_BASE_CD_KNOB_X = CD_LFO_SHAPES_X + 64;
@@ -243,7 +242,6 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent
LfoControllerDialog::~LfoControllerDialog()
{
m_userWaveBtn->disconnect( this );
//delete m_subWindow;
}
@@ -287,13 +285,6 @@ void LfoControllerDialog::contextMenuEvent( QContextMenuEvent * )
}
/*
void lfoControllerDialog::paintEvent( QPaintEvent * _pe )
{
QWidget::paintEvent( _pe );
}
*/
void LfoControllerDialog::modelChanged()
{
+55 -17
View File
@@ -33,6 +33,7 @@
#include <QMdiSubWindow>
#include <QMenuBar>
#include <QMessageBox>
#include <QShortcut>
#include <QSplitter>
#include <QWhatsThis>
@@ -97,7 +98,9 @@ MainWindow::MainWindow() :
ConfigManager* confMgr = ConfigManager::inst();
emit initProgress(tr("Preparing plugin browser"));
sideBar->appendTab( new PluginBrowser( splitter ) );
emit initProgress(tr("Preparing file browsers"));
sideBar->appendTab( new FileBrowser(
confMgr->userProjectsDir() + "*" +
confMgr->factoryProjectsDir(),
@@ -151,6 +154,7 @@ MainWindow::MainWindow() :
m_workspace = new QMdiArea( splitter );
// Load background
emit initProgress(tr("Loading background artwork"));
QString bgArtwork = ConfigManager::inst()->backgroundArtwork();
QImage bgImage;
if( !bgArtwork.isEmpty() )
@@ -232,12 +236,12 @@ void MainWindow::finalize()
project_menu->addAction( embed::getIconPixmap( "project_new" ),
tr( "&New" ),
this, SLOT( createNewProject() ),
Qt::CTRL + Qt::Key_N );
QKeySequence::New );
project_menu->addAction( embed::getIconPixmap( "project_open" ),
tr( "&Open..." ),
this, SLOT( openProject() ),
Qt::CTRL + Qt::Key_O );
QKeySequence::Open );
m_recentlyOpenedProjectsMenu = project_menu->addMenu(
embed::getIconPixmap( "project_open_recent" ),
@@ -250,7 +254,7 @@ void MainWindow::finalize()
project_menu->addAction( embed::getIconPixmap( "project_save" ),
tr( "&Save" ),
this, SLOT( saveProject() ),
Qt::CTRL + Qt::Key_S );
QKeySequence::Save );
project_menu->addAction( embed::getIconPixmap( "project_saveas" ),
tr( "Save &As..." ),
this, SLOT( saveProjectAs() ),
@@ -289,18 +293,29 @@ void MainWindow::finalize()
QMenu * edit_menu = new QMenu( this );
menuBar()->addMenu( edit_menu )->setText( tr( "&Edit" ) );
edit_menu->addAction( embed::getIconPixmap( "edit_undo" ),
m_undoAction = edit_menu->addAction( embed::getIconPixmap( "edit_undo" ),
tr( "Undo" ),
this, SLOT( undo() ),
Qt::CTRL + Qt::Key_Z );
edit_menu->addAction( embed::getIconPixmap( "edit_redo" ),
QKeySequence::Undo );
m_redoAction = edit_menu->addAction( embed::getIconPixmap( "edit_redo" ),
tr( "Redo" ),
this, SLOT( redo() ),
Qt::CTRL + Qt::Key_Y );
QKeySequence::Redo );
// Ensure that both (Ctrl+Y) and (Ctrl+Shift+Z) activate redo shortcut regardless of OS defaults
if (QKeySequence(QKeySequence::Redo) != QKeySequence(Qt::CTRL + Qt::Key_Y))
{
new QShortcut( QKeySequence( Qt::CTRL + Qt::Key_Y ), this, SLOT(redo()) );
}
if (QKeySequence(QKeySequence::Redo) != QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z ))
{
new QShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_Z ), this, SLOT(redo()) );
}
edit_menu->addSeparator();
edit_menu->addAction( embed::getIconPixmap( "setup_general" ),
tr( "Settings" ),
this, SLOT( showSettingsDialog() ) );
connect( edit_menu, SIGNAL(aboutToShow()), this, SLOT(updateUndoRedoButtons()) );
m_viewMenu = new QMenu( this );
menuBar()->addMenu( m_viewMenu )->setText( tr( "&View" ) );
@@ -379,7 +394,7 @@ void MainWindow::finalize()
ToolButton * project_open_recent = new ToolButton(
embed::getIconPixmap( "project_open_recent" ),
tr( "Recently opened project" ),
tr( "Recently opened projects" ),
this, SLOT( emptySlot() ), m_toolBar );
project_open_recent->setMenu( m_recentlyOpenedProjectsMenu );
project_open_recent->setPopupMode( ToolButton::InstantPopup );
@@ -732,6 +747,14 @@ void MainWindow::createNewProject()
{
Engine::getSong()->createNewProject();
}
QString default_template = ConfigManager::inst()->userTemplateDir()
+ "default.mpt";
//if we dont have a user default template, make one
if( !QFile::exists( default_template ) )
{
Engine::getSong()->saveProjectFile( default_template );
}
}
@@ -1059,35 +1082,37 @@ void MainWindow::updateViewMenu()
qa = new QAction(tr( "Volume as dBV" ), this);
qa->setData("displaydbv");
qa->setCheckable( true );
qa->setChecked( ConfigManager::inst()->value( "app", "displaydbv" ).
toInt() ? true : false );
qa->setChecked( ConfigManager::inst()->value( "app", "displaydbv" ).toInt() );
m_viewMenu->addAction(qa);
// Maybe this is impossible?
/* qa = new QAction(tr( "Tooltips" ), this);
qa->setData("tooltips");
qa->setCheckable( true );
qa->setChecked( ConfigManager::inst()->value( "tooltips", "disabled" ).
toInt() ? false : true );
qa->setChecked( !ConfigManager::inst()->value( "tooltips", "disabled" ).toInt() );
m_viewMenu->addAction(qa);
*/
// Should be doable.
qa = new QAction(tr( "Smooth scroll" ), this);
qa->setData("smoothscroll");
qa->setCheckable( true );
qa->setChecked( ConfigManager::inst()->value( "ui", "smoothscroll" ).
toInt() ? true : false );
qa->setChecked( ConfigManager::inst()->value( "ui", "smoothscroll" ).toInt() );
m_viewMenu->addAction(qa);
// Not yet.
/* qa = new QAction(tr( "One instrument track window" ), this);
qa->setData("oneinstrument");
qa->setCheckable( true );
qa->setChecked( ConfigManager::inst()->value( "ui", "oneinstrumenttrackwindow" ).
toInt() ? true : false );
qa->setChecked( ConfigManager::inst()->value( "ui", "oneinstrumenttrackwindow" ).toInt() );
m_viewMenu->addAction(qa);
*/
qa = new QAction(tr( "Enable note labels in piano roll" ), this);
qa->setData("printnotelabels");
qa->setCheckable( true );
qa->setChecked( ConfigManager::inst()->value( "ui", "printnotelabels" ).toInt() );
m_viewMenu->addAction(qa);
}
@@ -1116,6 +1141,11 @@ void MainWindow::updateConfig( QAction * _who )
ConfigManager::inst()->setValue( "ui", "oneinstrumenttrackwindow",
QString::number(checked) );
}
else if ( tag == "printnotelabels" )
{
ConfigManager::inst()->setValue( "ui", "printnotelabels",
QString::number(checked) );
}
}
@@ -1161,6 +1191,14 @@ void MainWindow::updatePlayPauseIcons()
}
void MainWindow::updateUndoRedoButtons()
{
// when the edit menu is shown, grey out the undo/redo buttons if there's nothing to undo/redo
// else, un-grey them
m_undoAction->setEnabled(Engine::projectJournal()->canUndo());
m_redoAction->setEnabled(Engine::projectJournal()->canRedo());
}
void MainWindow::undo()
+160 -54
View File
@@ -30,6 +30,7 @@
#include <QMessageBox>
#include <QSlider>
#include <QWhatsThis>
#include <QScrollArea>
#include "SetupDialog.h"
#include "TabBar.h"
@@ -105,6 +106,8 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
m_artworkDir( QDir::toNativeSeparators( ConfigManager::inst()->artworkDir() ) ),
m_flDir( QDir::toNativeSeparators( ConfigManager::inst()->flDir() ) ),
m_ladDir( QDir::toNativeSeparators( ConfigManager::inst()->ladspaDir() ) ),
m_gigDir( QDir::toNativeSeparators( ConfigManager::inst()->gigDir() ) ),
m_sf2Dir( QDir::toNativeSeparators( ConfigManager::inst()->sf2Dir() ) ),
#ifdef LMMS_HAVE_FLUIDSYNTH
m_defaultSoundfont( QDir::toNativeSeparators( ConfigManager::inst()->defaultSoundfont() ) ),
#endif
@@ -378,15 +381,34 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
dir_layout->setSpacing( 0 );
dir_layout->setMargin( 0 );
labelWidget( paths, tr( "Paths" ) );
QLabel * title = new QLabel( tr( "Directories" ), paths );
QFont f = title->font();
f.setBold( true );
title->setFont( pointSize<12>( f ) );
QScrollArea *pathScroll = new QScrollArea( paths );
QWidget *pathSelectors = new QWidget( ws );
QVBoxLayout *pathSelectorLayout = new QVBoxLayout;
pathScroll->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
pathScroll->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
pathScroll->resize( 362, pathsHeight - 50 );
pathScroll->move( 0, 30 );
pathSelectors->resize( 360, pathsHeight - 50 );
const int txtLength = 285;
const int btnStart = 305;
// working-dir
TabWidget * lmms_wd_tw = new TabWidget( tr(
"LMMS working directory" ).toUpper(),
paths );
pathSelectors );
lmms_wd_tw->setFixedHeight( 48 );
m_wdLineEdit = new QLineEdit( m_workingDir, lmms_wd_tw );
m_wdLineEdit->setGeometry( 10, 20, 300, 16 );
m_wdLineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_wdLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setWorkingDir( const QString & ) ) );
@@ -394,37 +416,19 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
embed::getIconPixmap( "project_open", 16, 16 ),
"", lmms_wd_tw );
workingdir_select_btn->setFixedSize( 24, 24 );
workingdir_select_btn->move( 320, 16 );
workingdir_select_btn->move( btnStart, 16 );
connect( workingdir_select_btn, SIGNAL( clicked() ), this,
SLOT( openWorkingDir() ) );
// vst-dir
TabWidget * vst_tw = new TabWidget( tr(
"VST-plugin directory" ).toUpper(),
paths );
vst_tw->setFixedHeight( 48 );
m_vdLineEdit = new QLineEdit( m_vstDir, vst_tw );
m_vdLineEdit->setGeometry( 10, 20, 300, 16 );
connect( m_vdLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setVSTDir( const QString & ) ) );
QPushButton * vstdir_select_btn = new QPushButton(
embed::getIconPixmap( "project_open", 16, 16 ),
"", vst_tw );
vstdir_select_btn->setFixedSize( 24, 24 );
vstdir_select_btn->move( 320, 16 );
connect( vstdir_select_btn, SIGNAL( clicked() ), this,
SLOT( openVSTDir() ) );
// artwork-dir
TabWidget * artwork_tw = new TabWidget( tr(
"Artwork directory" ).toUpper(),
paths );
"Themes directory" ).toUpper(),
pathSelectors );
artwork_tw->setFixedHeight( 48 );
m_adLineEdit = new QLineEdit( m_artworkDir, artwork_tw );
m_adLineEdit->setGeometry( 10, 20, 300, 16 );
m_adLineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_adLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setArtworkDir( const QString & ) ) );
@@ -432,7 +436,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
embed::getIconPixmap( "project_open", 16, 16 ),
"", artwork_tw );
artworkdir_select_btn->setFixedSize( 24, 24 );
artworkdir_select_btn->move( 320, 16 );
artworkdir_select_btn->move( btnStart, 16 );
connect( artworkdir_select_btn, SIGNAL( clicked() ), this,
SLOT( openArtworkDir() ) );
@@ -445,7 +449,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
m_baLineEdit = new QLineEdit( m_backgroundArtwork,
backgroundArtwork_tw );
m_baLineEdit->setGeometry( 10, 20, 300, 16 );
m_baLineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_baLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setBackgroundArtwork( const QString & ) ) );
@@ -453,7 +457,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
embed::getIconPixmap( "project_open", 16, 16 ),
"", backgroundArtwork_tw );
backgroundartworkdir_select_btn->setFixedSize( 24, 24 );
backgroundartworkdir_select_btn->move( 320, 16 );
backgroundartworkdir_select_btn->move( btnStart, 16 );
connect( backgroundartworkdir_select_btn, SIGNAL( clicked() ), this,
SLOT( openBackgroundArtwork() ) );
@@ -468,7 +472,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
fl_tw->setFixedHeight( 48 );
m_fdLineEdit = new QLineEdit( m_flDir, fl_tw );
m_fdLineEdit->setGeometry( 10, 20, 300, 16 );
m_fdLineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_fdLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setFLDir( const QString & ) ) );
@@ -476,28 +480,89 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
embed::getIconPixmap( "project_open", 16, 16 ),
"", fl_tw );
fldir_select_btn->setFixedSize( 24, 24 );
fldir_select_btn->move( 320, 16 );
fldir_select_btn->move( btnStart, 16 );
connect( fldir_select_btn, SIGNAL( clicked() ), this,
SLOT( openFLDir() ) );
// vst-dir
TabWidget * vst_tw = new TabWidget( tr(
"VST-plugin directory" ).toUpper(),
pathSelectors );
vst_tw->setFixedHeight( 48 );
m_vdLineEdit = new QLineEdit( m_vstDir, vst_tw );
m_vdLineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_vdLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setVSTDir( const QString & ) ) );
QPushButton * vstdir_select_btn = new QPushButton(
embed::getIconPixmap( "project_open", 16, 16 ),
"", vst_tw );
vstdir_select_btn->setFixedSize( 24, 24 );
vstdir_select_btn->move( btnStart, 16 );
connect( vstdir_select_btn, SIGNAL( clicked() ), this,
SLOT( openVSTDir() ) );
// gig-dir
TabWidget * gig_tw = new TabWidget( tr(
"GIG directory" ).toUpper(),
pathSelectors );
gig_tw->setFixedHeight( 48 );
m_gigLineEdit = new QLineEdit( m_gigDir, gig_tw );
m_gigLineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_gigLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setGIGDir( const QString & ) ) );
QPushButton * gigdir_select_btn = new QPushButton(
embed::getIconPixmap( "project_open", 16, 16 ),
"", gig_tw );
gigdir_select_btn->setFixedSize( 24, 24 );
gigdir_select_btn->move( btnStart, 16 );
connect( gigdir_select_btn, SIGNAL( clicked() ), this,
SLOT( openGIGDir() ) );
// sf2-dir
TabWidget * sf2_tw = new TabWidget( tr(
"SF2 directory" ).toUpper(),
pathSelectors );
sf2_tw->setFixedHeight( 48 );
m_sf2LineEdit = new QLineEdit( m_sf2Dir, sf2_tw );
m_sf2LineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_sf2LineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setSF2Dir( const QString & ) ) );
QPushButton * sf2dir_select_btn = new QPushButton(
embed::getIconPixmap( "project_open", 16, 16 ),
"", sf2_tw );
sf2dir_select_btn->setFixedSize( 24, 24 );
sf2dir_select_btn->move( btnStart, 16 );
connect( sf2dir_select_btn, SIGNAL( clicked() ), this,
SLOT( openSF2Dir() ) );
// LADSPA-dir
TabWidget * lad_tw = new TabWidget( tr(
"LADSPA plugin paths" ).toUpper(),
"LADSPA plugin directories" ).toUpper(),
paths );
lad_tw->setFixedHeight( 48 );
m_ladLineEdit = new QLineEdit( m_ladDir, lad_tw );
m_ladLineEdit->setGeometry( 10, 20, 300, 16 );
m_ladLineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_ladLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setLADSPADir( const QString & ) ) );
QPushButton * laddir_select_btn = new QPushButton(
embed::getIconPixmap( "project_open", 16, 16 ),
embed::getIconPixmap( "add_folder", 16, 16 ),
"", lad_tw );
laddir_select_btn->setFixedSize( 24, 24 );
laddir_select_btn->move( 320, 16 );
laddir_select_btn->move( btnStart, 16 );
connect( laddir_select_btn, SIGNAL( clicked() ), this,
SLOT( openLADSPADir() ) );
#ifdef LMMS_HAVE_STK
// STK-dir
TabWidget * stk_tw = new TabWidget( tr(
@@ -506,7 +571,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
stk_tw->setFixedHeight( 48 );
m_stkLineEdit = new QLineEdit( m_stkDir, stk_tw );
m_stkLineEdit->setGeometry( 10, 20, 300, 16 );
m_stkLineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_stkLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setSTKDir( const QString & ) ) );
@@ -514,7 +579,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
embed::getIconPixmap( "project_open", 16, 16 ),
"", stk_tw );
stkdir_select_btn->setFixedSize( 24, 24 );
stkdir_select_btn->move( 320, 16 );
stkdir_select_btn->move( btnStart, 16 );
connect( stkdir_select_btn, SIGNAL( clicked() ), this,
SLOT( openSTKDir() ) );
#endif
@@ -526,7 +591,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
sf_tw->setFixedHeight( 48 );
m_sfLineEdit = new QLineEdit( m_defaultSoundfont, sf_tw );
m_sfLineEdit->setGeometry( 10, 20, 300, 16 );
m_sfLineEdit->setGeometry( 10, 20, txtLength, 16 );
connect( m_sfLineEdit, SIGNAL( textChanged( const QString & ) ), this,
SLOT( setDefaultSoundfont( const QString & ) ) );
@@ -534,34 +599,42 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
embed::getIconPixmap( "project_open", 16, 16 ),
"", sf_tw );
sf_select_btn->setFixedSize( 24, 24 );
sf_select_btn->move( 320, 16 );
sf_select_btn->move( btnStart, 16 );
connect( sf_select_btn, SIGNAL( clicked() ), this,
SLOT( openDefaultSoundfont() ) );
#endif
pathSelectors->setLayout( pathSelectorLayout );
dir_layout->addWidget( lmms_wd_tw );
dir_layout->addSpacing( 10 );
dir_layout->addWidget( vst_tw );
dir_layout->addSpacing( 10 );
dir_layout->addWidget( artwork_tw );
dir_layout->addSpacing( 10 );
dir_layout->addWidget( backgroundArtwork_tw );
dir_layout->addSpacing( 10 );
dir_layout->addWidget( fl_tw );
dir_layout->addSpacing( 10 );
dir_layout->addWidget( lad_tw );
pathSelectorLayout->addWidget( lmms_wd_tw );
pathSelectorLayout->addSpacing( 10 );
pathSelectorLayout->addWidget( gig_tw );
pathSelectorLayout->addSpacing( 10 );
pathSelectorLayout->addWidget( sf2_tw );
pathSelectorLayout->addSpacing( 10 );
pathSelectorLayout->addWidget( vst_tw );
pathSelectorLayout->addSpacing( 10 );
pathSelectorLayout->addWidget( lad_tw );
#ifdef LMMS_HAVE_STK
dir_layout->addSpacing( 10 );
dir_layout->addWidget( stk_tw );
pathSelectorLayout->addSpacing( 10 );
pathSelectorLayout->addWidget( stk_tw );
#endif
#ifdef LMMS_HAVE_FLUIDSYNTH
dir_layout->addSpacing( 10 );
dir_layout->addWidget( sf_tw );
pathSelectorLayout->addSpacing( 10 );
pathSelectorLayout->addWidget( sf_tw );
#endif
dir_layout->addStretch();
pathSelectorLayout->addWidget( fl_tw );
pathSelectorLayout->addSpacing( 10 );
pathSelectorLayout->addWidget( artwork_tw );
pathSelectorLayout->addSpacing( 10 );
pathSelectorLayout->addStretch();
pathSelectorLayout->addWidget( backgroundArtwork_tw );
pathSelectorLayout->addSpacing( 10 );
dir_layout->addWidget( pathSelectors );
pathScroll->setWidget( pathSelectors );
pathScroll->setWidgetResizable( true );
@@ -905,6 +978,8 @@ void SetupDialog::accept()
ConfigManager::inst()->setWorkingDir( m_workingDir );
ConfigManager::inst()->setVSTDir( m_vstDir );
ConfigManager::inst()->setGIGDir( m_gigDir );
ConfigManager::inst()->setSF2Dir( m_sf2Dir );
ConfigManager::inst()->setArtworkDir( m_artworkDir );
ConfigManager::inst()->setFLDir( m_flDir );
ConfigManager::inst()->setLADSPADir( m_ladDir );
@@ -1128,6 +1203,28 @@ void SetupDialog::openWorkingDir()
}
}
void SetupDialog::openGIGDir()
{
QString new_dir = FileDialog::getExistingDirectory( this,
tr( "Choose your GIG directory" ),
m_gigDir );
if( new_dir != QString::null )
{
m_gigLineEdit->setText( new_dir );
}
}
void SetupDialog::openSF2Dir()
{
QString new_dir = FileDialog::getExistingDirectory( this,
tr( "Choose your SF2 directory" ),
m_sf2Dir );
if( new_dir != QString::null )
{
m_sf2LineEdit->setText( new_dir );
}
}
@@ -1158,6 +1255,16 @@ void SetupDialog::setVSTDir( const QString & _vd )
m_vstDir = _vd;
}
void SetupDialog::setGIGDir(const QString &_gd)
{
m_gigDir = _gd;
}
void SetupDialog::setSF2Dir(const QString &_sfd)
{
m_sf2Dir = _sfd;
}
@@ -1218,7 +1325,6 @@ void SetupDialog::openLADSPADir()
void SetupDialog::openSTKDir()
{
#ifdef LMMS_HAVE_STK
+3 -3
View File
@@ -52,7 +52,7 @@ StringPairDrag::StringPairDrag( const QString & _key, const QString & _value,
}
QString txt = _key + ":" + _value;
QMimeData * m = new QMimeData();
m->setData( mimeType(), txt.toLatin1() );
m->setData( mimeType(), txt.toUtf8() );
setMimeData( m );
start( Qt::IgnoreAction );
}
@@ -95,7 +95,7 @@ bool StringPairDrag::processDragEnterEvent( QDragEnterEvent * _dee,
QString StringPairDrag::decodeMimeKey( const QMimeData * mimeData )
{
return( QString( mimeData->data( mimeType() ) ).section( ':', 0, 0 ) );
return( QString::fromUtf8( mimeData->data( mimeType() ) ).section( ':', 0, 0 ) );
}
@@ -103,7 +103,7 @@ QString StringPairDrag::decodeMimeKey( const QMimeData * mimeData )
QString StringPairDrag::decodeMimeValue( const QMimeData * mimeData )
{
return( QString( mimeData->data( mimeType() ) ).section( ':', 1, -1 ) );
return( QString::fromUtf8( mimeData->data( mimeType() ) ).section( ':', 1, -1 ) );
}
+67 -34
View File
@@ -22,6 +22,7 @@
*
*/
#include <algorithm>
#include <QApplication>
#include <QLayout>
@@ -157,50 +158,75 @@ void TrackContainerView::removeTrackView( TrackView * _tv )
void TrackContainerView::moveTrackViewUp( TrackView * _tv )
void TrackContainerView::moveTrackView( TrackView * trackView, int indexTo )
{
for( int i = 1; i < m_trackViews.size(); ++i )
{
TrackView * t = m_trackViews[i];
if( t == _tv )
{
BBTrack::swapBBTracks( t->getTrack(),
m_trackViews[i - 1]->getTrack() );
m_scrollLayout->removeWidget( t );
m_scrollLayout->insertWidget( i - 1, t );
qSwap( m_tc->m_tracks[i-1], m_tc->m_tracks[i] );
m_trackViews.swap( i - 1, i );
realignTracks();
break;
}
}
// Can't move out of bounds
if ( indexTo >= m_trackViews.size() || indexTo < 0 ) { return; }
// Does not need to move to itself
int indexFrom = m_trackViews.indexOf( trackView );
if ( indexFrom == indexTo ) { return; }
BBTrack::swapBBTracks( trackView->getTrack(),
m_trackViews[indexTo]->getTrack() );
m_scrollLayout->removeWidget( trackView );
m_scrollLayout->insertWidget( indexTo, trackView );
Track * track = m_tc->m_tracks[indexFrom];
m_tc->m_tracks.remove( indexFrom );
m_tc->m_tracks.insert( indexTo, track );
m_trackViews.move( indexFrom, indexTo );
realignTracks();
}
void TrackContainerView::moveTrackViewDown( TrackView * _tv )
void TrackContainerView::moveTrackViewUp( TrackView * trackView )
{
for( int i = 0; i < m_trackViews.size()-1; ++i )
{
TrackView * t = m_trackViews[i];
if( t == _tv )
{
BBTrack::swapBBTracks( t->getTrack(),
m_trackViews[i + 1]->getTrack() );
m_scrollLayout->removeWidget( t );
m_scrollLayout->insertWidget( i + 1, t );
qSwap( m_tc->m_tracks[i], m_tc->m_tracks[i+1] );
m_trackViews.swap( i, i + 1 );
realignTracks();
break;
}
}
int index = m_trackViews.indexOf( trackView );
moveTrackView( trackView, index - 1 );
}
void TrackContainerView::moveTrackViewDown( TrackView * trackView )
{
int index = m_trackViews.indexOf( trackView );
moveTrackView( trackView, index + 1 );
}
void TrackContainerView::scrollToTrackView( TrackView * _tv )
{
if (!m_trackViews.contains(_tv))
{
qWarning("TrackContainerView::scrollToTrackView: TrackView is not owned by this");
}
else
{
int currentScrollTop = m_scrollArea->verticalScrollBar()->value();
int scrollAreaHeight = m_scrollArea->size().height();
int trackViewTop = _tv->pos().y();
int trackViewBottom = trackViewTop + _tv->size().height();
// displayed_location = widget_location - currentScrollTop
// want to make sure that the widget top has displayed location > 0,
// and widget bottom < scrollAreaHeight
// trackViewTop - scrollY > 0 && trackViewBottom - scrollY < scrollAreaHeight
// therefore scrollY < trackViewTop && scrollY > trackViewBottom - scrollAreaHeight
int newScroll = std::max( trackViewBottom-scrollAreaHeight, std::min(currentScrollTop, trackViewTop) );
m_scrollArea->verticalScrollBar()->setValue(newScroll);
}
}
void TrackContainerView::realignTracks()
{
@@ -220,11 +246,18 @@ void TrackContainerView::realignTracks()
void TrackContainerView::createTrackView( Track * _t )
TrackView * TrackContainerView::createTrackView( Track * _t )
{
//m_tc->addJournalCheckPoint();
_t->createView( this );
// Avoid duplicating track views
for( trackViewList::iterator it = m_trackViews.begin();
it != m_trackViews.end(); ++it )
{
if ( ( *it )->getTrack() == _t ) { return ( *it ); }
}
return _t->createView( this );
}
+14 -11
View File
@@ -624,11 +624,6 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
float level = getLevel( mouseEvent->y() );
int x = mouseEvent->x();
if( mouseEvent->x() <= VALUES_WIDTH )
{
update();
return;
}
x -= VALUES_WIDTH;
if( m_action == MOVE_VALUE )
{
@@ -699,12 +694,12 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
{
if( QApplication::overrideCursor() )
{
if( QApplication::overrideCursor()->shape() != Qt::SizeAllCursor )
if( QApplication::overrideCursor()->shape() != Qt::SizeAllCursor )
{
while( QApplication::overrideCursor() != NULL )
{
QApplication::restoreOverrideCursor();
}
while( QApplication::overrideCursor() != NULL )
{
QApplication::restoreOverrideCursor();
}
QCursor c( Qt::SizeAllCursor );
QApplication::setOverrideCursor(
@@ -2304,7 +2299,15 @@ void AutomationEditorWindow::dropEvent( QDropEvent *_de )
journallingObject( val.toInt() ) );
if( mod != NULL )
{
m_editor->m_pattern->addObject( mod );
bool added = m_editor->m_pattern->addObject( mod );
if ( !added )
{
TextFloat::displayMessage( mod->displayName(),
tr( "Model is already connected "
"to this pattern." ),
embed::getIconPixmap( "automation" ),
2000 );
}
setCurrentPattern( m_editor->m_pattern );
}
}
+184 -103
View File
@@ -1081,7 +1081,16 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke )
if( ke->modifiers() & Qt::ControlModifier )
{
ke->accept();
selectAll();
if (ke->modifiers() & Qt::ShiftModifier)
{
// Ctrl + Shift + A = deselect all notes
clearSelectedNotes();
}
else
{
// Ctrl + A = select all notes
selectAll();
}
update();
}
break;
@@ -1848,54 +1857,50 @@ void PianoRoll::computeSelectedNotes(bool shift)
void PianoRoll::mouseReleaseEvent(QMouseEvent * me )
void PianoRoll::mouseReleaseEvent( QMouseEvent * me )
{
s_textFloat->hide();
bool mustRepaint = false;
s_textFloat->hide();
if( me->button() & Qt::LeftButton )
{
m_mouseDownLeft = false;
mustRepaint = true;
if( m_action == ActionSelectNotes && m_editMode == ModeSelect )
{
// select the notes within the selection rectangle and
// then destroy the selection rectangle
computeSelectedNotes(
me->modifiers() & Qt::ShiftModifier );
}
else if( m_action == ActionMoveNote )
{
// we moved one or more notes so they have to be
// moved properly according to new starting-
// time in the note-array of pattern
m_pattern->rearrangeAllNotes();
}
if( m_action == ActionMoveNote || m_action == ActionResizeNote )
{
// if we only moved one note, deselect it so we can
// edit the notes in the note edit area
if( selectionCount() == 1 )
{
clearSelectedNotes();
}
}
}
if( me->button() & Qt::RightButton )
{
m_mouseDownRight = false;
mustRepaint = true;
}
if( me->button() & Qt::LeftButton &&
m_editMode == ModeSelect &&
m_action == ActionSelectNotes )
{
// select the notes within the selection rectangle and
// then destroy the selection rectangle
computeSelectedNotes( me->modifiers() & Qt::ShiftModifier );
}
else if( me->button() & Qt::LeftButton &&
m_action == ActionMoveNote )
{
// we moved one or more notes so they have to be
// moved properly according to new starting-
// time in the note-array of pattern
m_pattern->rearrangeAllNotes();
}
if( me->button() & Qt::LeftButton &&
( m_action == ActionMoveNote || m_action == ActionResizeNote ) )
{
// if we only moved one note, deselect it so we can
// edit the notes in the note edit area
if( selectionCount() == 1 )
{
clearSelectedNotes();
}
}
if( hasValidPattern() )
{
// turn off all notes that are playing
@@ -1907,7 +1912,8 @@ void PianoRoll::mouseReleaseEvent(QMouseEvent * me )
Note *note = *it;
if( note->isPlaying() )
{
m_pattern->instrumentTrack()->pianoModel()->handleKeyRelease( note->key() );
m_pattern->instrumentTrack()->pianoModel()->
handleKeyRelease( note->key() );
note->setIsPlaying( false );
}
@@ -1915,11 +1921,11 @@ void PianoRoll::mouseReleaseEvent(QMouseEvent * me )
}
// stop playing keys that we let go of
m_pattern->instrumentTrack()->pianoModel()->handleKeyRelease( m_lastKey );
m_pattern->instrumentTrack()->pianoModel()->
handleKeyRelease( m_lastKey );
}
m_currentNote = NULL;
m_action = ActionNone;
if( m_editMode == ModeDraw )
@@ -2092,7 +2098,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
if ( isUnderPosition ) { testPlayNote( n ); }
// If note is the one under the cursor or is selected when alt is
// not pressed
if ( isUnderPosition || ( n->selected() && !altPressed ) )
if ( ( isUnderPosition && !isSelection() ) || ( n->selected() && !altPressed ) )
{
if( m_noteEditMode == NoteEditVolume )
{
@@ -2428,7 +2434,7 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
{
if( m_moveBoundaryLeft + off_ticks < 0 )
{
off_ticks += 0 - (off_ticks + m_moveBoundaryLeft);
off_ticks -= (off_ticks + m_moveBoundaryLeft);
}
if( m_moveBoundaryTop + off_key > NumKeys )
{
@@ -2436,92 +2442,161 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
}
if( m_moveBoundaryBottom + off_key < 0 )
{
off_key += 0 - (m_moveBoundaryBottom + off_key);
off_key -= (m_moveBoundaryBottom + off_key);
}
}
int shift_offset = 0;
int shift_ref_pos = -1;
// get note-vector of current pattern
const NoteVector & notes = m_pattern->notes();
// will be our iterator in the following loop
NoteVector::ConstIterator it = notes.begin();
int sNotes = selectionCount();
while( it != notes.end() )
if (m_action == ActionMoveNote)
{
Note *note = *it;
const int pos = note->pos().getTicks();
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
{
Note *note = *it;
if( note->selected() )
{
if( ! ( shift && ! m_startedWithShift ) )
{
// moving note
int pos_ticks = note->oldPos().getTicks() + off_ticks;
int key_num = note->oldKey() + off_key;
// ticks can't be negative
pos_ticks = qMax(0, pos_ticks);
// upper/lower bound checks on key_num
key_num = qMax(0, key_num);
key_num = qMin(key_num, NumKeys);
note->setPos( MidiTime( pos_ticks ) );
note->setKey( key_num );
}
else if( shift && ! m_startedWithShift )
{
// quick resize, toggled by holding shift after starting a note move, but not before
int ticks_new = note->oldLength().getTicks() + off_ticks;
if( ticks_new <= 0 )
{
ticks_new = 1;
}
note->setLength( MidiTime( ticks_new ) );
m_lenOfNewNotes = note->length();
}
}
}
}
else if (m_action == ActionResizeNote)
{
// When resizing notes:
// If shift is not pressed, resize the selected notes but do not rearrange them
// 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( m_action == ActionResizeNote && shift &&
( note->selected() || ctrl || sNotes == 1 ) )
if (shift)
{
int shifted_pos = note->oldPos().getTicks() + shift_offset;
if( shifted_pos && pos == shift_ref_pos )
// Algorithm:
// Relative to the starting point of the left-most selected note,
// all selected note start-points and *endpoints* (not length) should be scaled by a calculated factor.
// This factor is such that the endpoint of the note whose handle is being dragged should lie under the cursor.
// first, determine the start-point of the left-most selected note:
int stretchStartTick = -1;
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
{
shifted_pos -= off_ticks;
}
note->setPos( MidiTime( shifted_pos ) );
}
if( note->selected() )
{
if( m_action == ActionMoveNote && ! ( shift && ! m_startedWithShift ) )
{
// moving note
int pos_ticks = note->oldPos().getTicks() + off_ticks;
int key_num = note->oldKey() + off_key;
// ticks can't be negative
pos_ticks = qMax(0, pos_ticks);
// upper/lower bound checks on key_num
key_num = qMax(0, key_num);
key_num = qMin(key_num, NumKeys);
note->setPos( MidiTime( pos_ticks ) );
note->setKey( key_num );
}
else if( m_action == ActionResizeNote )
{
// resizing note
int ticks_new = note->oldLength().getTicks() + off_ticks;
if( ticks_new <= 0 )
Note *note = *it;
if (note->selected() && (stretchStartTick < 0 || note->oldPos().getTicks() < stretchStartTick))
{
ticks_new = 1;
stretchStartTick = note->oldPos().getTicks();
}
else if( shift )
}
// determine the ending tick of the right-most selected note
Note *posteriorNote = nullptr;
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
{
Note *note = *it;
if (note->selected() && (posteriorNote == nullptr ||
note->oldPos().getTicks() + note->oldLength().getTicks() >
posteriorNote->oldPos().getTicks() + posteriorNote->oldLength().getTicks()))
{
// when holding shift: update the offset used to shift
// the following notes
if( pos > shift_ref_pos )
posteriorNote = note;
}
}
int posteriorEndTick = posteriorNote->pos().getTicks() + posteriorNote->length().getTicks();
// end-point of the note whose handle is being dragged:
int stretchEndTick = m_currentNote->oldPos().getTicks() + m_currentNote->oldLength().getTicks();
// Calculate factor by which to scale the start-point and end-point of all selected notes
float scaleFactor = (float)(stretchEndTick - stretchStartTick + off_ticks) / qMax(1, stretchEndTick - stretchStartTick);
scaleFactor = qMax(0.0f, scaleFactor);
// process all selected notes & determine how much the endpoint of the right-most note was shifted
int posteriorDeltaThisFrame = 0;
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
{
Note *note = *it;
if(note->selected())
{
// scale relative start and end positions by scaleFactor
int newStart = stretchStartTick + scaleFactor *
(note->oldPos().getTicks() - stretchStartTick);
int newEnd = stretchStartTick + scaleFactor *
(note->oldPos().getTicks()+note->oldLength().getTicks() - stretchStartTick);
// if not holding alt, quantize the offsets
if(!alt)
{
shift_offset += off_ticks;
shift_ref_pos = pos;
// quantize start time
int oldStart = note->oldPos().getTicks();
int startDiff = newStart - oldStart;
startDiff = floor(startDiff / quantization()) * quantization();
newStart = oldStart + startDiff;
// quantize end time
int oldEnd = oldStart + note->oldLength().getTicks();
int endDiff = newEnd - oldEnd;
endDiff = floor(endDiff / quantization()) * quantization();
newEnd = oldEnd + endDiff;
}
int newLength = qMax(1, newEnd-newStart);
if (note == posteriorNote)
{
posteriorDeltaThisFrame = (newStart+newLength) -
(note->pos().getTicks() + note->length().getTicks());
}
note->setLength( MidiTime(newLength) );
note->setPos( MidiTime(newStart) );
m_lenOfNewNotes = note->length();
}
}
if (ctrl || selectionCount() == 1)
{
// if holding ctrl or only one note is selected, reposition posterior notes
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
{
Note *note = *it;
if (!note->selected() && note->pos().getTicks() >= posteriorEndTick)
{
int newStart = note->pos().getTicks() + posteriorDeltaThisFrame;
note->setPos( MidiTime(newStart) );
}
}
note->setLength( MidiTime( ticks_new ) );
m_lenOfNewNotes = note->length();
}
else if( m_action == ActionMoveNote && ( shift && ! m_startedWithShift ) )
{
// quick resize, toggled by holding shift after starting a note move, but not before
int ticks_new = note->oldLength().getTicks() + off_ticks;
if( ticks_new <= 0 )
{
ticks_new = 1;
}
note->setLength( MidiTime( ticks_new ) );
m_lenOfNewNotes = note->length();
}
}
++it;
else
{
// shift is not pressed; stretch length of selected notes but not their position
for (NoteVector::ConstIterator it = notes.begin(); it != notes.end(); ++it )
{
Note *note = *it;
if (note->selected())
{
int newLength = note->oldLength() + off_ticks;
newLength = qMax(1, newLength);
note->setLength( MidiTime(newLength) );
m_lenOfNewNotes = note->length();
}
}
}
}
m_pattern->dataChanged();
@@ -4230,3 +4305,9 @@ QSize PianoRollWindow::sizeHint() const
{
return {m_toolBar->sizeHint().width() + 10, INITIAL_PIANOROLL_HEIGHT};
}
void PianoRollWindow::focusInEvent(QFocusEvent * event)
{
// when the window is given focus, also give focus to the actual piano roll
m_editor->setFocus(event->reason());
}
+4 -6
View File
@@ -67,7 +67,6 @@ QPixmap * Fader::s_knob = NULL;
Fader::Fader( FloatModel * _model, const QString & _name, QWidget * _parent ) :
QWidget( _parent ),
FloatModelView( _model, this ),
m_model( _model ),
m_fPeakValue_L( 0.0 ),
m_fPeakValue_R( 0.0 ),
m_persistentPeak_L( 0.0 ),
@@ -114,7 +113,6 @@ Fader::Fader( FloatModel * _model, const QString & _name, QWidget * _parent ) :
Fader::Fader( FloatModel * model, const QString & name, QWidget * parent, QPixmap * back, QPixmap * leds, QPixmap * knob ) :
QWidget( parent ),
FloatModelView( model, this ),
m_model( model ),
m_fPeakValue_L( 0.0 ),
m_fPeakValue_R( 0.0 ),
m_persistentPeak_L( 0.0 ),
@@ -170,7 +168,7 @@ void Fader::mouseMoveEvent( QMouseEvent *mouseEvent )
{
int dy = m_moveStartPoint - mouseEvent->globalY();
float delta = dy * ( m_model->maxValue() - m_model->minValue() ) / (float) ( height() - ( *m_knob ).height() );
float delta = dy * ( model()->maxValue() - model()->minValue() ) / (float) ( height() - ( *m_knob ).height() );
model()->setValue( m_startValue + delta );
@@ -256,11 +254,11 @@ void Fader::wheelEvent ( QWheelEvent *ev )
if ( ev->delta() > 0 )
{
m_model->incValue( 1 );
model()->incValue( 1 );
}
else
{
m_model->incValue( -1 );
model()->incValue( -1 );
}
updateTextFloat();
s_textFloat->setVisibilityTimeOut( 1000 );
@@ -326,7 +324,7 @@ void Fader::updateTextFloat()
}
else
{
s_textFloat->setText( m_description + " " + QString("%1 ").arg( m_displayConversion ? m_model->value() * 100 : m_model->value() ) + " " + m_unit );
s_textFloat->setText( m_description + " " + QString("%1 ").arg( m_displayConversion ? model()->value() * 100 : model()->value() ) + " " + m_unit );
}
s_textFloat->moveGlobal( this, QPoint( width() - ( *m_knob ).width() - 5, knobPosY() - 46 ) );
}
+2 -1
View File
@@ -65,7 +65,8 @@ TextFloat * Knob::s_textFloat = NULL;
m_volumeKnob( false ), \
m_volumeRatio( 100.0, 0.0, 1000000.0 ), \
m_buttonPressed( false ), \
m_angle( -10 )
m_angle( -10 ), \
m_lineWidth(0)
Knob::Knob( knobTypes _knob_num, QWidget * _parent, const QString & _name ) :
DEFAULT_KNOB_INITIALIZER_LIST,
+91
View File
@@ -0,0 +1,91 @@
/*
* LeftRightNav.cpp - side-by-side left-facing and right-facing arrows for navigation (looks like < > )
*
* Copyright (c) 2015 Colin Wallace <wallacoloo/at/gmail.com>
*
* This file is part of LMMS - http://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 "LeftRightNav.h"
#include "ToolTip.h"
#include "embed.h"
LeftRightNav::LeftRightNav(QWidget *parent)
: QWidget(parent),
m_layout(this),
m_leftBtn(this, tr("Previous")),
m_rightBtn(this, tr("Next"))
{
m_layout.setContentsMargins(0, 0, 0, 0);
m_layout.setSpacing(2);
m_leftBtn.setCheckable(false);
m_rightBtn.setCheckable(false);
m_leftBtn.setCursor(Qt::PointingHandCursor);
m_rightBtn.setCursor(Qt::PointingHandCursor);
m_leftBtn.setActiveGraphic(embed::getIconPixmap(
"stepper-left-press"));
m_rightBtn.setActiveGraphic(embed::getIconPixmap(
"stepper-right-press" ));
m_leftBtn.setInactiveGraphic(embed::getIconPixmap(
"stepper-left" ));
m_rightBtn.setInactiveGraphic(embed::getIconPixmap(
"stepper-right"));
connect(&m_leftBtn, SIGNAL(clicked()), this,
SIGNAL(onNavLeft()));
connect(&m_rightBtn, SIGNAL(clicked()), this,
SIGNAL(onNavRight()));
ToolTip::add(&m_leftBtn, tr("Previous"));
ToolTip::add(&m_rightBtn, tr("Next"));
m_leftBtn.setWindowTitle(tr("Previous"));
m_rightBtn.setWindowTitle(tr("Next"));
// AutomatableButton's right click menu (contains irrelevant options like copying and pasting values)
m_leftBtn.setContextMenuPolicy(Qt::NoContextMenu);
m_rightBtn.setContextMenuPolicy(Qt::NoContextMenu);
m_layout.addWidget(&m_leftBtn);
m_layout.addWidget(&m_rightBtn);
}
PixmapButton* LeftRightNav::getLeftBtn()
{
return &m_leftBtn;
}
PixmapButton* LeftRightNav::getRightBtn()
{
return &m_rightBtn;
}
void LeftRightNav::setShortcuts(const QKeySequence &leftShortcut, const QKeySequence &rightShortcut)
{
m_leftBtn.setShortcut(leftShortcut);
m_rightBtn.setShortcut(rightShortcut);
ToolTip::add(&m_leftBtn, tr("Previous (%1)").arg(leftShortcut.toString()));
ToolTip::add(&m_rightBtn, tr("Next (%1)").arg(rightShortcut.toString()));
}
+11 -1
View File
@@ -130,7 +130,17 @@ void PixmapButton::setInactiveGraphic( const QPixmap & _pm, bool _update )
}
}
QSize PixmapButton::sizeHint() const
{
if( ( model() != NULL && model()->value() ) || m_pressed )
{
return m_activePixmap.size();
}
else
{
return m_inactivePixmap.size();
}
}
+84 -1
View File
@@ -66,6 +66,7 @@
#include "Knob.h"
#include "LcdSpinBox.h"
#include "LedCheckbox.h"
#include "LeftRightNav.h"
#include "MainWindow.h"
#include "MidiClient.h"
#include "MidiPortMenu.h"
@@ -80,6 +81,7 @@
#include "StringPairDrag.h"
#include "TabWidget.h"
#include "ToolTip.h"
#include "TrackContainerView.h"
#include "TrackLabelButton.h"
#include "ValueBuffer.h"
#include "volume.h"
@@ -1280,13 +1282,36 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
generalSettingsLayout->setContentsMargins( 8, 18, 8, 8 );
generalSettingsLayout->setSpacing( 6 );
QWidget* nameAndChangeTrackWidget = new QWidget( generalSettingsWidget );
QHBoxLayout* nameAndChangeTrackLayout = new QHBoxLayout( nameAndChangeTrackWidget );
nameAndChangeTrackLayout->setContentsMargins( 0, 0, 0, 0 );
nameAndChangeTrackLayout->setSpacing( 2 );
// setup line edit for changing instrument track name
m_nameLineEdit = new QLineEdit;
m_nameLineEdit->setFont( pointSize<9>( m_nameLineEdit->font() ) );
connect( m_nameLineEdit, SIGNAL( textChanged( const QString & ) ),
this, SLOT( textChanged( const QString & ) ) );
generalSettingsLayout->addWidget( m_nameLineEdit );
m_nameLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
nameAndChangeTrackLayout->addWidget(m_nameLineEdit);
// set up left/right arrows for changing instrument
m_leftRightNav = new LeftRightNav(this);
connect( m_leftRightNav, SIGNAL( onNavLeft() ), this,
SLOT( viewPrevInstrument() ) );
connect( m_leftRightNav, SIGNAL( onNavRight() ), this,
SLOT( viewNextInstrument() ) );
m_leftRightNav->setWhatsThis(
tr( "Use these controls to view and edit the next/previous track in the song editor." ) );
// m_leftRightNav->setShortcuts();
nameAndChangeTrackLayout->addWidget(m_leftRightNav);
generalSettingsLayout->addWidget( nameAndChangeTrackWidget );
QHBoxLayout* basicControlsLayout = new QHBoxLayout;
basicControlsLayout->setSpacing( 3 );
@@ -1693,3 +1718,61 @@ void InstrumentTrackWindow::loadSettings( const QDomElement& thisElement )
m_itv->m_tlb->setChecked( true );
}
}
void InstrumentTrackWindow::viewInstrumentInDirection(int d)
{
// helper routine for viewNextInstrument, viewPrevInstrument
// d=-1 to view the previous instrument,
// d=+1 to view the next instrument
const QList<TrackView *> &trackViews = m_itv->trackContainerView()->trackViews();
int idxOfMe = trackViews.indexOf(m_itv);
// search for the next InstrumentTrackView (i.e. skip AutomationViews, etc)
// sometimes, the next InstrumentTrackView may already be open, in which case
// replace our window contents with the *next* closed Instrument Track and
// give focus to the InstrumentTrackView we skipped.
int idxOfNext = idxOfMe;
InstrumentTrackView *newView = nullptr;
InstrumentTrackView *bringToFront = nullptr;
do
{
idxOfNext = (idxOfNext + d + trackViews.size()) % trackViews.size();
newView = dynamic_cast<InstrumentTrackView*>(trackViews[idxOfNext]);
// the window that should be brought to focus is the FIRST InstrumentTrackView that comes after us
if (bringToFront == nullptr && newView != nullptr)
{
bringToFront = newView;
}
// if the next instrument doesn't have an active window, then exit loop & load that one into our window.
if (newView != nullptr && !newView->m_tlb->isChecked())
{
break;
}
} while (idxOfNext != idxOfMe);
// avoid reloading the window if there is only one instrument, as that will just change the active tab
if (idxOfNext != idxOfMe)
{
// save current window pos and then hide the window by unchecking its button in the track list
QPoint curPos = parentWidget()->pos();
m_itv->m_tlb->setChecked(false);
// enable the new window by checking its track list button & moving it to where our window just was
newView->m_tlb->setChecked(true);
newView->getInstrumentTrackWindow()->parentWidget()->move(curPos);
// scroll the SongEditor/BB-editor to make sure the new trackview label is visible
bringToFront->trackContainerView()->scrollToTrackView(bringToFront);
}
bringToFront->getInstrumentTrackWindow()->setFocus();
}
void InstrumentTrackWindow::viewNextInstrument()
{
viewInstrumentInDirection(+1);
}
void InstrumentTrackWindow::viewPrevInstrument()
{
viewInstrumentInDirection(-1);
}