1/* 2 * Copyright (c) 2015-2021 Meltytech, LLC 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18import QtQuick 2.12 19import QtQuick.Controls 2.12 20import QtQuick.Layouts 1.12 21import Shotcut.Controls 1.0 as Shotcut 22 23Item { 24 width: 350 25 height: 250 26 Component.onCompleted: { 27 filter.blockSignals = true 28 if (filter.isNew) { 29 // Set preset parameter values 30 filter.set('0', 40) 31 filter.set('1', 4) 32 filter.set('2', 0.9) 33 filter.set('3', 0.75) 34 filter.set('4', 0) 35 filter.set('5', -22) 36 filter.set('6', -28) 37 filter.savePreset(preset.parameters, qsTr('Quick fix')) 38 39 filter.set('0', 50) 40 filter.set('1', 1.5) 41 filter.set('2', 0.1) 42 filter.set('3', 0.75) 43 filter.set('4', -1.5) 44 filter.set('5', -10) 45 filter.set('6', -20) 46 filter.savePreset(preset.parameters, qsTr('Small hall')) 47 48 filter.set('0', 40) 49 filter.set('1', 20) 50 filter.set('2', 0.5) 51 filter.set('3', 0.75) 52 filter.set('4', 0) 53 filter.set('5', -10) 54 filter.set('6', -30) 55 filter.savePreset(preset.parameters, qsTr('Large hall')) 56 57 filter.set('0', 6) 58 filter.set('1', 15) 59 filter.set('2', 0.9) 60 filter.set('3', 0.1) 61 filter.set('4', -10) 62 filter.set('5', -10) 63 filter.set('6', -10) 64 filter.savePreset(preset.parameters, qsTr('Sewer')) 65 66 filter.set('0', 6) 67 filter.set('1', 15) 68 filter.set('2', 0.9) 69 filter.set('3', .1) 70 filter.set('4', -10) 71 filter.set('5', -10) 72 filter.set('6', -10) 73 filter.savePreset(preset.parameters, qsTr('Church')) 74 75 // Set default parameter values 76 filter.set('0', 30) 77 filter.set('1', 7.5) 78 filter.set('2', 0.5) 79 filter.set('3', 0.75) 80 filter.set('4', 0) 81 filter.set('5', -10) 82 filter.set('6', -17.5) 83 filter.savePreset(preset.parameters) 84 } 85 filter.blockSignals = false 86 filter.changed() 87 setControls() 88 } 89 90 function setControls() { 91 sliderRoom.value = filter.getDouble('0') 92 sliderTime.value = filter.getDouble('1') 93 sliderDamp.value = filter.getDouble('2') * sliderDamp.maximumValue 94 sliderInput.value = filter.getDouble('3') * sliderInput.maximumValue 95 sliderDry.value = filter.getDouble('4') 96 sliderReflection.value = filter.getDouble('5') 97 sliderTail.value = filter.getDouble('6') 98 } 99 100 GridLayout { 101 anchors.fill: parent 102 anchors.margins: 8 103 columns: 3 104 105 Label { 106 text: qsTr('Preset') 107 Layout.alignment: Qt.AlignRight 108 } 109 Shotcut.Preset { 110 id: preset 111 parameters: ['0', '1', '2', '3', '4', '5', '6'] 112 Layout.columnSpan: 2 113 onPresetSelected: setControls() 114 } 115 116 Label { 117 text: qsTr('Room size') 118 Layout.alignment: Qt.AlignRight 119 Shotcut.HoverTip {text: qsTr('The size of the room, in meters. Excessively large, and excessively small values will make it sound a bit unrealistic. Values of around 30 sound good.')} 120 } 121 Shotcut.SliderSpinner { 122 id: sliderRoom 123 minimumValue: 1 124 maximumValue: 300 125 suffix: ' m' 126 value: filter.getDouble('0') 127 onValueChanged: { 128 filter.set('0', value) 129 } 130 } 131 Shotcut.UndoButton { 132 onClicked: sliderRoom.value = 30 133 } 134 135 Label { 136 text: qsTr('Reverb time') 137 Layout.alignment: Qt.AlignRight 138 } 139 Shotcut.SliderSpinner { 140 id: sliderTime 141 minimumValue: .1 142 maximumValue: 30 143 decimals: 1 144 suffix: ' s' 145 value: filter.getDouble('1') 146 onValueChanged: { 147 filter.set('1', value) 148 } 149 } 150 Shotcut.UndoButton { 151 onClicked: sliderTime.value = 7.5 152 } 153 154 Label { 155 text: qsTr('Damping') 156 Layout.alignment: Qt.AlignRight 157 Shotcut.HoverTip {text: qsTr('This controls the high frequency damping (a lowpass filter), values near 1 will make it sound very bright, values near 0 will make it sound very dark.')} 158 } 159 Shotcut.SliderSpinner { 160 id: sliderDamp 161 minimumValue: 0 162 maximumValue: 100 163 decimals: 1 164 suffix: ' %' 165 value: filter.getDouble('2') * maximumValue 166 onValueChanged: { 167 filter.set('2', value / maximumValue) 168 } 169 } 170 Shotcut.UndoButton { 171 onClicked: sliderDamp.value = 0.5 * sliderDamp.maximumValue 172 } 173 174 Label { 175 text: qsTr('Input bandwidth') 176 Layout.alignment: Qt.AlignRight 177 Shotcut.HoverTip {text: qsTr('This is like a damping control for the input, it has a similar effect to the damping control, but is subtly different.')} 178 } 179 Shotcut.SliderSpinner { 180 id: sliderInput 181 minimumValue: 0 182 maximumValue: 100 183 decimals: 1 184 suffix: ' %' 185 value: filter.getDouble('3') * maximumValue 186 onValueChanged: { 187 filter.set('3', value / maximumValue) 188 } 189 } 190 Shotcut.UndoButton { 191 onClicked: sliderInput.value = 0.75 * sliderInput.maximumValue 192 } 193 194 Label { 195 text: qsTr('Dry signal level') 196 Layout.alignment: Qt.AlignRight 197 Shotcut.HoverTip {text: qsTr('The amount of dry signal to be mixed with the reverberated signal.')} 198 } 199 Shotcut.SliderSpinner { 200 id: sliderDry 201 minimumValue: -70 202 maximumValue: 0 203 suffix: ' dB' 204 decimals: 1 205 value: filter.getDouble('4') 206 onValueChanged: { 207 filter.set('4', value) 208 } 209 } 210 Shotcut.UndoButton { 211 onClicked: sliderDry.value = 0 212 } 213 214 Label { 215 text: qsTr('Early reflection level') 216 Layout.alignment: Qt.AlignRight 217 Shotcut.HoverTip {text: qsTr('The distance from the threshold where the knee curve starts.')} 218 } 219 Shotcut.SliderSpinner { 220 id: sliderReflection 221 minimumValue: -70 222 maximumValue: 0 223 suffix: ' dB' 224 value: filter.getDouble('5') 225 onValueChanged: { 226 filter.set('5', value) 227 } 228 } 229 230 Shotcut.UndoButton { 231 onClicked: sliderReflection.value = -10 232 } 233 Label { 234 text: qsTr('Tail level') 235 Layout.alignment: Qt.AlignRight 236 Shotcut.HoverTip {text: qsTr('The quantity of early reflections (scatter reflections directly from the source).')} 237 } 238 Shotcut.SliderSpinner { 239 id: sliderTail 240 minimumValue: -70 241 maximumValue: 0 242 decimals: 1 243 suffix: ' dB' 244 value: filter.getDouble('6') 245 onValueChanged: { 246 filter.set('6', value) 247 } 248 } 249 Shotcut.UndoButton { 250 onClicked: sliderTail.value = -17.5 251 } 252 253 Label { 254 Layout.columnSpan: 3 255 text: qsTr('About reverb') 256 font.underline: true 257 MouseArea { 258 anchors.fill: parent 259 onClicked: Qt.openUrlExternally('https://wiki.audacityteam.org/wiki/GVerb') 260 } 261 } 262 263 Item { 264 Layout.fillHeight: true; 265 } 266 } 267} 268