/[svn]/qsampler/trunk/src/qsamplerChannelFxForm.cpp
ViewVC logotype

Contents of /qsampler/trunk/src/qsamplerChannelFxForm.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2388 - (show annotations) (download)
Sat Dec 29 19:12:58 2012 UTC (11 years, 3 months ago) by capela
File size: 11790 byte(s)
- Preparations for Qt5 migration. (TESTING)
1 // qsamplerChannelFxForm.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2010-2012, rncbc aka Rui Nuno Capela. All rights reserved.
5 Copyright (C) 2008, Christian Schoenebeck
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21 *****************************************************************************/
22
23 #include "qsamplerAbout.h"
24 #include "qsamplerChannelFxForm.h"
25 #include "qsamplerFxSendsModel.h"
26
27 // let's not reinvent the wheel for audio routing
28 #include "qsamplerChannel.h"
29
30 #include <math.h>
31
32 #include <QAbstractButton>
33 #include <QLineEdit>
34 #include <QHeaderView>
35 #include <QMap>
36
37 namespace { // private namespace
38
39 static const char* _midiControllerName(int iMidiCtrl) {
40 switch (iMidiCtrl) {
41 case 0: return "Bank select MSB";
42 case 1: return "Modulation MSB";
43 case 2: return "Breath Controller";
44 case 4: return "Foot Controller MSB";
45 case 5: return "Portamento Time MSB";
46 case 6: return "(N)RPN Data Byte";
47 case 7: return "Main Volume";
48 case 8: return "Balance";
49 case 10: return "Panorama";
50 case 11: return "Expression";
51 case 12: return "Effect Control 1";
52 case 13: return "Effect Control 2";
53 case 16: return "General Purpose Controller 1";
54 case 17: return "General Purpose Controller 2";
55 case 18: return "General Purpose Controller 3";
56 case 19: return "General Purpose Controller 4";
57 case 32: return "Bank select LSB";
58 case 63: return "LSB for Controllers 0?31";
59 case 64: return "Hold 1";
60 case 65: return "Portamento";
61 case 66: return "Sostenuto";
62 case 67: return "Soft Pedal";
63 case 68: return "Legato Footswitch";
64 case 69: return "Hold 2";
65 case 70: return "Sound Controller 1 (Sound Variation)";
66 case 71: return "Sound Controller 2 (Harmonic Content)";
67 case 72: return "Sound Controller 3 (Release Time)";
68 case 73: return "Sound Controller 4 (Attack Time)";
69 case 74: return "Sound Controller 5 (Brightness)";
70 case 75: return "Sound Controller 6";
71 case 76: return "Sound Controller 7";
72 case 77: return "Sound Controller 8";
73 case 78: return "Sound Controller 9";
74 case 79: return "Sound Controller 10";
75 case 80: return "General Purpose 5";
76 case 81: return "General Purpose 6";
77 case 82: return "General Purpose 7";
78 case 83: return "General Purpose 8";
79 case 84: return "Portamento Control";
80 case 91: return "Effects 1 Depth";
81 case 92: return "Effects 2 Depth";
82 case 93: return "Effects 3 Depth";
83 case 94: return "Effects 4 Depth";
84 case 95: return "Effects 5 Depth";
85 case 96: return "Data Increment (N)RPN";
86 case 97: return "Data Decrement (N)RPN";
87 case 98: return "NRPN LSB";
88 case 99: return "NRPN MSB";
89 case 100: return "RPN LSB";
90 case 101: return "RPN MSB";
91 case 120: return "All Sounds Off";
92 case 121: return "Controller Reset";
93 case 122: return "Local Control on/off";
94 case 123: return "All Notes Off";
95 case 124: return "Omni Off";
96 case 125: return "Omni On";
97 case 126: return "Mono On / Poly Off";
98 case 127: return "Poly On / Mono Off";
99 default: return "";
100 }
101 }
102
103 } // private namespace
104
105
106 namespace QSampler {
107
108 ChannelFxForm::ChannelFxForm (
109 Channel* pSamplerChannel, QWidget* pParent, Qt::WindowFlags wflags )
110 : QDialog(pParent, wflags)
111 {
112 m_ui.setupUi(this);
113
114 m_pSamplerChannel = pSamplerChannel;
115
116 m_pAudioDevice = NULL;
117
118 FxSendsModel* pModel =
119 new FxSendsModel(m_pSamplerChannel->channelID(), m_ui.SendsListView);
120 m_ui.SendsListView->setModel(pModel);
121 #if QT_VERSION >= 0x040300
122 m_ui.SendsListView->setSelectionRectVisible(true);
123 #endif
124
125 const int iRowHeight = m_ui.audioRoutingTable->fontMetrics().height() + 4;
126 m_ui.audioRoutingTable->verticalHeader()->setDefaultSectionSize(iRowHeight);
127 m_ui.audioRoutingTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
128 ChannelRoutingModel* pRoutingModel =
129 new ChannelRoutingModel(m_ui.audioRoutingTable);
130 m_ui.audioRoutingTable->setModel(pRoutingModel);
131 ChannelRoutingDelegate* pRoutingDelegate =
132 new ChannelRoutingDelegate(m_ui.audioRoutingTable);
133 m_ui.audioRoutingTable->setItemDelegate(pRoutingDelegate);
134 #if QT_VERSION >= 0x050000
135 m_ui.audioRoutingTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
136 #else
137 m_ui.audioRoutingTable->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
138 #endif
139 // m_ui.audioRoutingTable->verticalHeader()->hide();
140
141 QAbstractButton* pApplyButton =
142 m_ui.buttonBox->button(QDialogButtonBox::Apply);
143 pApplyButton->setEnabled(false);
144 pApplyButton->setIcon(QIcon(":/images/formEdit.png"));
145
146 QAbstractButton* pCancelButton =
147 m_ui.buttonBox->button(QDialogButtonBox::Cancel);
148 pCancelButton->setIcon(QIcon(":/images/formRemove.png"));
149
150 QAbstractButton* pOkButton =
151 m_ui.buttonBox->button(QDialogButtonBox::Ok);
152 pOkButton->setIcon(QIcon(":/images/formAccept.png"));
153
154 QAbstractButton* pResetButton =
155 m_ui.buttonBox->button(QDialogButtonBox::Reset);
156 pResetButton->setEnabled(false);
157 pResetButton->setToolTip("Revert all changes.");
158
159 m_ui.destroyPushButton->setEnabled(false);
160
161 m_ui.mainParametersGroupBox->setEnabled(false);
162 m_ui.audioRoutingGroupBox->setEnabled(false);
163
164 for (int i = 0; i < 128; ++i) {
165 m_ui.depthCtrlComboBox->addItem(
166 QString("[") + QString::number(i) + "] " + _midiControllerName(i)
167 );
168 }
169
170 connect(
171 m_ui.buttonBox, SIGNAL(clicked(QAbstractButton*)),
172 this, SLOT(onButtonClicked(QAbstractButton*))
173 );
174 connect(
175 m_ui.createPushButton, SIGNAL(clicked()),
176 this, SLOT(onCreateFxSend())
177 );
178 connect(
179 m_ui.destroyPushButton, SIGNAL(clicked()),
180 this, SLOT(onDestroyFxSend())
181 );
182 connect(
183 pModel, SIGNAL(fxSendsDirtyChanged(bool)),
184 pApplyButton, SLOT(setEnabled(bool))
185 );
186 connect(
187 pModel, SIGNAL(fxSendsDirtyChanged(bool)),
188 pResetButton, SLOT(setEnabled(bool))
189 );
190 connect(
191 m_ui.SendsListView, SIGNAL(clicked(const QModelIndex&)),
192 this, SLOT(onFxSendSelection(const QModelIndex&))
193 );
194 connect(
195 m_ui.depthCtrlComboBox, SIGNAL(activated(int)),
196 this, SLOT(onDepthCtrlChanged(int))
197 );
198 connect(
199 m_ui.depthSpinBox, SIGNAL(valueChanged(int)),
200 this, SLOT(onCurrentSendDepthChanged(int))
201 );
202 connect(
203 pRoutingModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
204 this, SLOT(updateTableCellRenderers(const QModelIndex&, const QModelIndex&))
205 );
206 connect(
207 pRoutingModel, SIGNAL(modelReset()),
208 this, SLOT(updateTableCellRenderers())
209 );
210 connect(
211 pRoutingModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
212 this, SLOT(onRoutingTableChanged())
213 );
214 }
215
216 ChannelFxForm::~ChannelFxForm() {
217 if (m_pAudioDevice) delete m_pAudioDevice;
218 }
219
220 void ChannelFxForm::onButtonClicked(QAbstractButton* button) {
221 FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
222 switch (m_ui.buttonBox->buttonRole(button)) {
223 case QDialogButtonBox::AcceptRole:
224 case QDialogButtonBox::ApplyRole:
225 pModel->applyToSampler();
226 // force a refresh of the parameter control elements
227 onFxSendSelection(m_ui.SendsListView->currentIndex());
228 break;
229 case QDialogButtonBox::ResetRole:
230 pModel->cleanRefresh();
231 // force a refresh of the parameter control elements
232 onFxSendSelection(m_ui.SendsListView->currentIndex());
233 break;
234 default: // to avoid gcc warnings
235 break;
236 }
237 }
238
239 void ChannelFxForm::onFxSendSelection(const QModelIndex& index) {
240 const bool bValid = index.isValid();
241 m_ui.destroyPushButton->setEnabled(bValid);
242 m_ui.mainParametersGroupBox->setEnabled(bValid);
243 m_ui.audioRoutingGroupBox->setEnabled(bValid);
244
245 FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
246 FxSend* pFxSend = pModel->fxSend(index);
247
248 // clear routing model
249 ChannelRoutingModel* pRoutingModel =
250 (ChannelRoutingModel*) m_ui.audioRoutingTable->model();
251 pRoutingModel->refresh(NULL, ChannelRoutingMap());
252 pRoutingModel->routingMap().clear(); // Reset routing change map.
253 if (m_pAudioDevice) {
254 delete m_pAudioDevice;
255 m_pAudioDevice = NULL;
256 }
257
258 if (!pFxSend) return;
259
260 // update routing model
261 if (m_pSamplerChannel->audioDevice() >= 0) {
262 m_pAudioDevice =
263 new Device(Device::Audio, m_pSamplerChannel->audioDevice());
264 pRoutingModel->refresh(m_pAudioDevice, pFxSend->audioRouting());
265 }
266
267 m_ui.depthCtrlComboBox->setCurrentIndex(pFxSend->sendDepthMidiCtrl());
268 m_ui.depthSpinBox->setValue(
269 int(::round(pFxSend->currentDepth() * 100.0))
270 );
271 }
272
273 void ChannelFxForm::onCreateFxSend() {
274 FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
275 pModel->addFxSend();
276 }
277
278 void ChannelFxForm::onDestroyFxSend() {
279 FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
280 pModel->removeFxSend(m_ui.SendsListView->currentIndex());
281 }
282
283 void ChannelFxForm::onDepthCtrlChanged(int iMidiCtrl) {
284 FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
285 const QModelIndex index = m_ui.SendsListView->currentIndex();
286 FxSend* pFxSend = pModel->fxSend(index);
287 if (!pFxSend) return;
288
289 pFxSend->setSendDepthMidiCtrl(iMidiCtrl);
290 pModel->onExternalModifiication(index);
291 }
292
293 void ChannelFxForm::onCurrentSendDepthChanged(int depthPercent) {
294 FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
295 const QModelIndex index = m_ui.SendsListView->currentIndex();
296 FxSend* pFxSend = pModel->fxSend(index);
297 if (!pFxSend) return;
298
299 if (depthPercent == int( ::round(pFxSend->currentDepth() * 100.0) ))
300 return; // nothing changed actually
301
302 pFxSend->setCurrentDepth(double(depthPercent) / 100.0);
303 pModel->onExternalModifiication(index);
304 }
305
306 void ChannelFxForm::onRoutingTableChanged() {
307 ChannelRoutingModel* pRoutingModel =
308 (ChannelRoutingModel*) m_ui.audioRoutingTable->model();
309 if (pRoutingModel->routingMap().size() <= 0)
310 return; // no changes
311
312 FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
313 const QModelIndex index = m_ui.SendsListView->currentIndex();
314 FxSend* pFxSend = pModel->fxSend(index);
315 if (!pFxSend) {
316 pRoutingModel->routingMap().clear(); // reset routing change map
317 return;
318 }
319
320 ChannelRoutingMap routingMap = pRoutingModel->routingMap();
321 for (
322 ChannelRoutingMap::iterator iter = routingMap.begin();
323 iter != routingMap.end(); ++iter
324 ) pFxSend->setAudioChannel(iter.key(), iter.value());
325
326 pRoutingModel->routingMap().clear(); // reset routing change map
327
328 pModel->onExternalModifiication(index);
329 }
330
331 void ChannelFxForm::updateTableCellRenderers() {
332 ChannelRoutingModel* pRoutingModel =
333 (ChannelRoutingModel*) m_ui.audioRoutingTable->model();
334 const int rows = pRoutingModel->rowCount();
335 const int cols = pRoutingModel->columnCount();
336 updateTableCellRenderers(
337 pRoutingModel->index(0, 0),
338 pRoutingModel->index(rows - 1, cols - 1)
339 );
340 }
341
342 void ChannelFxForm::updateTableCellRenderers (
343 const QModelIndex& topLeft, const QModelIndex& bottomRight )
344 {
345 ChannelRoutingModel* pRoutingModel =
346 (ChannelRoutingModel*) m_ui.audioRoutingTable->model();
347 for (int r = topLeft.row(); r <= bottomRight.row(); r++) {
348 for (int c = topLeft.column(); c <= bottomRight.column(); c++) {
349 const QModelIndex index = pRoutingModel->index(r, c);
350 m_ui.audioRoutingTable->openPersistentEditor(index);
351 }
352 }
353 }
354
355 } // namespace QSampler
356
357 // end of qsamplerChannelFxForm.cpp

  ViewVC Help
Powered by ViewVC