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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1667 by schoenebeck, Mon Feb 4 23:24:19 2008 UTC revision 1707 by schoenebeck, Tue Feb 19 22:26:33 2008 UTC
# Line 23  Line 23 
23  #include "qsamplerChannelFxForm.h"  #include "qsamplerChannelFxForm.h"
24  #include "qsamplerFxSendsModel.h"  #include "qsamplerFxSendsModel.h"
25    
26    // let's not reinvent the wheel for audio routing
27    #include "qsamplerChannel.h"
28    
29    #include <math.h>
30    
31  #include <QAbstractButton>  #include <QAbstractButton>
32    #include <QLineEdit>
33    #include <QHeaderView>
34    #include <QMap>
35    
36    namespace { // private namespace
37    
38    static const char* _midiControllerName(int iMidiCtrl) {
39            switch (iMidiCtrl) {
40                    case 0:   return "Bank select MSB";
41                    case 1:   return "Modulation MSB";
42                    case 2:   return "Breath Controller";
43                    case 4:   return "Foot Controller MSB";
44                    case 5:   return "Portamento Time MSB";
45                    case 6:   return "(N)RPN Data Byte";
46                    case 7:   return "Main Volume";
47                    case 8:   return "Balance";
48                    case 10:  return "Panorama";
49                    case 11:  return "Expression";
50                    case 12:  return "Effect Control 1";
51                    case 13:  return "Effect Control 2";
52                    case 16:  return "General Purpose Controller 1";
53                    case 17:  return "General Purpose Controller 2";
54                    case 18:  return "General Purpose Controller 3";
55                    case 19:  return "General Purpose Controller 4";
56                    case 32:  return "Bank select LSB";
57                    case 63:  return "LSB for Controllers 0?31";
58                    case 64:  return "Hold 1";
59                    case 65:  return "Portamento";
60                    case 66:  return "Sostenuto";
61                    case 67:  return "Soft Pedal";
62                    case 68:  return "Legato Footswitch";
63                    case 69:  return "Hold 2";
64                    case 70:  return "Sound Controller 1 (Sound Variation)";
65                    case 71:  return "Sound Controller 2 (Harmonic Content)";
66                    case 72:  return "Sound Controller 3 (Release Time)";
67                    case 73:  return "Sound Controller 4 (Attack Time)";
68                    case 74:  return "Sound Controller 5 (Brightness)";
69                    case 75:  return "Sound Controller 6";
70                    case 76:  return "Sound Controller 7";
71                    case 77:  return "Sound Controller 8";
72                    case 78:  return "Sound Controller 9";
73                    case 79:  return "Sound Controller 10";
74                    case 80:  return "General Purpose 5";
75                    case 81:  return "General Purpose 6";
76                    case 82:  return "General Purpose 7";
77                    case 83:  return "General Purpose 8";
78                    case 84:  return "Portamento Control";
79                    case 91:  return "Effects 1 Depth";
80                    case 92:  return "Effects 2 Depth";
81                    case 93:  return "Effects 3 Depth";
82                    case 94:  return "Effects 4 Depth";
83                    case 95:  return "Effects 5 Depth";
84                    case 96:  return "Data Increment (N)RPN";
85                    case 97:  return "Data Decrement (N)RPN";
86                    case 98:  return "NRPN LSB";
87                    case 99:  return "NRPN MSB";
88                    case 100: return "RPN LSB";
89                    case 101: return "RPN MSB";
90                    case 120: return "All Sounds Off";
91                    case 121: return "Controller Reset";
92                    case 122: return "Local Control on/off";
93                    case 123: return "All Notes Off";
94                    case 124: return "Omni Off";
95                    case 125: return "Omni On";
96                    case 126: return "Mono On / Poly Off";
97                    case 127: return "Poly On / Mono Off";
98                    default: return "";
99            }
100    }
101    
102    } // private namespace
103    
104    
105  namespace QSampler {  namespace QSampler {
106    
107  ChannelFxForm::ChannelFxForm (  ChannelFxForm::ChannelFxForm (
108          int SamplerChannelID, QWidget* pParent, Qt::WindowFlags wflags )          Channel* pSamplerChannel, QWidget* pParent, Qt::WindowFlags wflags )
109          : QDialog(pParent, wflags)          : QDialog(pParent, wflags)
110  {  {
111          m_ui.setupUi(this);          m_ui.setupUi(this);
112    
113          m_SamplerChannelID = SamplerChannelID;          m_pSamplerChannel = pSamplerChannel;
114    
115            m_pAudioDevice = NULL;
116    
117          FxSendsModel* pModel =          FxSendsModel* pModel =
118                  new FxSendsModel(SamplerChannelID, m_ui.SendsListView);                  new FxSendsModel(m_pSamplerChannel->channelID(), m_ui.SendsListView);
119          m_ui.SendsListView->setModel(pModel);          m_ui.SendsListView->setModel(pModel);
120    #if QT_VERSION >= 0x040300
121            m_ui.SendsListView->setSelectionRectVisible(true);
122    #endif
123    
124            const int iRowHeight = m_ui.audioRoutingTable->fontMetrics().height() + 4;
125            m_ui.audioRoutingTable->verticalHeader()->setDefaultSectionSize(iRowHeight);
126            m_ui.audioRoutingTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
127            ChannelRoutingModel* pRoutingModel =
128                    new ChannelRoutingModel(m_ui.audioRoutingTable);
129            m_ui.audioRoutingTable->setModel(pRoutingModel);
130            ChannelRoutingDelegate* pRoutingDelegate =
131                    new ChannelRoutingDelegate(m_ui.audioRoutingTable);
132            m_ui.audioRoutingTable->setItemDelegate(pRoutingDelegate);
133            m_ui.audioRoutingTable->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
134    //      m_ui.audioRoutingTable->verticalHeader()->hide();
135    
136          QAbstractButton* pApplyButton =          QAbstractButton* pApplyButton =
137                  m_ui.buttonBox->button(QDialogButtonBox::Apply);                  m_ui.buttonBox->button(QDialogButtonBox::Apply);
# Line 55  ChannelFxForm::ChannelFxForm ( Line 149  ChannelFxForm::ChannelFxForm (
149          QAbstractButton* pResetButton =          QAbstractButton* pResetButton =
150                  m_ui.buttonBox->button(QDialogButtonBox::Reset);                  m_ui.buttonBox->button(QDialogButtonBox::Reset);
151          pResetButton->setEnabled(false);          pResetButton->setEnabled(false);
152            pResetButton->setToolTip("Revert all changes.");
153    
154          m_ui.destroyPushButton->setEnabled(false);          m_ui.destroyPushButton->setEnabled(false);
155    
156            m_ui.mainParametersGroupBox->setEnabled(false);
157            m_ui.audioRoutingGroupBox->setEnabled(false);
158    
159            for (int i = 0; i < 128; ++i) {
160                    m_ui.depthCtrlComboBox->addItem(
161                            QString("[") + QString::number(i) + "] " + _midiControllerName(i)
162                    );
163            }
164    
165          connect(          connect(
166                  m_ui.buttonBox, SIGNAL(clicked(QAbstractButton*)),                  m_ui.buttonBox, SIGNAL(clicked(QAbstractButton*)),
167                  this, SLOT(onButtonClicked(QAbstractButton*))                  this, SLOT(onButtonClicked(QAbstractButton*))
# Line 82  ChannelFxForm::ChannelFxForm ( Line 186  ChannelFxForm::ChannelFxForm (
186                  m_ui.SendsListView, SIGNAL(clicked(const QModelIndex&)),                  m_ui.SendsListView, SIGNAL(clicked(const QModelIndex&)),
187                  this, SLOT(onFxSendSelection(const QModelIndex&))                  this, SLOT(onFxSendSelection(const QModelIndex&))
188          );          );
189            connect(
190                    m_ui.depthCtrlComboBox, SIGNAL(activated(int)),
191                    this, SLOT(onDepthCtrlChanged(int))
192            );
193            connect(
194                    m_ui.depthSpinBox, SIGNAL(valueChanged(int)),
195                    this, SLOT(onCurrentSendDepthChanged(int))
196            );
197            connect(
198                    pRoutingModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
199                    this, SLOT(updateTableCellRenderers(const QModelIndex&, const QModelIndex&))
200            );
201            connect(
202                    pRoutingModel, SIGNAL(modelReset()),
203                    this, SLOT(updateTableCellRenderers())
204            );
205            connect(
206                    pRoutingModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
207                    this, SLOT(onRoutingTableChanged())
208            );
209  }  }
210    
211  ChannelFxForm::~ChannelFxForm() {  ChannelFxForm::~ChannelFxForm() {
212            if (m_pAudioDevice) delete m_pAudioDevice;
213  }  }
214    
215  void ChannelFxForm::onButtonClicked(QAbstractButton* button) {  void ChannelFxForm::onButtonClicked(QAbstractButton* button) {
# Line 93  void ChannelFxForm::onButtonClicked(QAbs Line 218  void ChannelFxForm::onButtonClicked(QAbs
218                  case QDialogButtonBox::AcceptRole:                  case QDialogButtonBox::AcceptRole:
219                  case QDialogButtonBox::ApplyRole:                  case QDialogButtonBox::ApplyRole:
220                          pModel->applyToSampler();                          pModel->applyToSampler();
221                            // force a refresh of the parameter control elements
222                            onFxSendSelection(m_ui.SendsListView->currentIndex());
223                          break;                          break;
224                  case QDialogButtonBox::ResetRole:                  case QDialogButtonBox::ResetRole:
225                          pModel->cleanRefresh();                          pModel->cleanRefresh();
226                            // force a refresh of the parameter control elements
227                            onFxSendSelection(m_ui.SendsListView->currentIndex());
228                          break;                          break;
229                  default: // to avoid gcc warnings                  default: // to avoid gcc warnings
230                          break;                          break;
# Line 103  void ChannelFxForm::onButtonClicked(QAbs Line 232  void ChannelFxForm::onButtonClicked(QAbs
232  }  }
233    
234  void ChannelFxForm::onFxSendSelection(const QModelIndex& index) {  void ChannelFxForm::onFxSendSelection(const QModelIndex& index) {
235          m_ui.destroyPushButton->setEnabled(index.isValid());          const bool bValid = index.isValid();
236            m_ui.destroyPushButton->setEnabled(bValid);
237            m_ui.mainParametersGroupBox->setEnabled(bValid);
238            m_ui.audioRoutingGroupBox->setEnabled(bValid);
239    
240            FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
241            FxSend* pFxSend = pModel->fxSend(index);
242    
243            // clear routing model
244            ChannelRoutingModel* pRoutingModel =
245                    (ChannelRoutingModel*) m_ui.audioRoutingTable->model();
246            pRoutingModel->refresh(NULL, ChannelRoutingMap());
247            pRoutingModel->routingMap().clear(); // Reset routing change map.
248            if (m_pAudioDevice) {
249                    delete m_pAudioDevice;
250                    m_pAudioDevice = NULL;
251            }
252    
253            if (!pFxSend) return;
254    
255            // update routing model
256            if (m_pSamplerChannel->audioDevice() >= 0) {
257                    m_pAudioDevice =
258                            new Device(Device::Audio, m_pSamplerChannel->audioDevice());
259                    pRoutingModel->refresh(m_pAudioDevice, pFxSend->audioRouting());
260            }
261    
262            m_ui.depthCtrlComboBox->setCurrentIndex(pFxSend->sendDepthMidiCtrl());
263            m_ui.depthSpinBox->setValue(
264                    int(::round(pFxSend->currentDepth() * 100.0))
265            );
266  }  }
267    
268  void ChannelFxForm::onCreateFxSend() {  void ChannelFxForm::onCreateFxSend() {
# Line 116  void ChannelFxForm::onDestroyFxSend() { Line 275  void ChannelFxForm::onDestroyFxSend() {
275          pModel->removeFxSend(m_ui.SendsListView->currentIndex());          pModel->removeFxSend(m_ui.SendsListView->currentIndex());
276  }  }
277    
278    void ChannelFxForm::onDepthCtrlChanged(int iMidiCtrl) {
279            FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
280            const QModelIndex index = m_ui.SendsListView->currentIndex();
281            FxSend* pFxSend = pModel->fxSend(index);
282            if (!pFxSend) return;
283    
284            pFxSend->setSendDepthMidiCtrl(iMidiCtrl);
285            pModel->onExternalModifiication(index);
286    }
287    
288    void ChannelFxForm::onCurrentSendDepthChanged(int depthPercent) {
289            FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
290            const QModelIndex index = m_ui.SendsListView->currentIndex();
291            FxSend* pFxSend = pModel->fxSend(index);
292            if (!pFxSend) return;
293    
294            if (depthPercent == int( ::round(pFxSend->currentDepth() * 100.0) ))
295                    return; // nothing changed actually
296    
297            pFxSend->setCurrentDepth(double(depthPercent) / 100.0);
298            pModel->onExternalModifiication(index);
299    }
300    
301    void ChannelFxForm::onRoutingTableChanged() {
302            ChannelRoutingModel* pRoutingModel =
303                    (ChannelRoutingModel*) m_ui.audioRoutingTable->model();
304            if (pRoutingModel->routingMap().size() <= 0)
305                    return; // no changes
306    
307            FxSendsModel* pModel = (FxSendsModel*) m_ui.SendsListView->model();
308            const QModelIndex index = m_ui.SendsListView->currentIndex();
309            FxSend* pFxSend = pModel->fxSend(index);
310            if (!pFxSend) {
311                    pRoutingModel->routingMap().clear(); // reset routing change map
312                    return;
313            }
314    
315            ChannelRoutingMap routingMap = pRoutingModel->routingMap();
316            for (
317                    ChannelRoutingMap::iterator iter = routingMap.begin();
318                    iter != routingMap.end(); ++iter
319            ) pFxSend->setAudioChannel(iter.key(), iter.value());
320    
321            pRoutingModel->routingMap().clear(); // reset routing change map
322    
323            pModel->onExternalModifiication(index);
324    }
325    
326    void ChannelFxForm::updateTableCellRenderers() {
327            ChannelRoutingModel* pRoutingModel =
328                    (ChannelRoutingModel*) m_ui.audioRoutingTable->model();
329            const int rows = pRoutingModel->rowCount();
330            const int cols = pRoutingModel->columnCount();
331            updateTableCellRenderers(
332                    pRoutingModel->index(0, 0),
333                    pRoutingModel->index(rows - 1, cols - 1)
334            );
335    }
336    
337    void ChannelFxForm::updateTableCellRenderers (
338            const QModelIndex& topLeft, const QModelIndex& bottomRight )
339    {
340            ChannelRoutingModel* pRoutingModel =
341                    (ChannelRoutingModel*) m_ui.audioRoutingTable->model();
342            for (int r = topLeft.row(); r <= bottomRight.row(); r++) {
343                    for (int c = topLeft.column(); c <= bottomRight.column(); c++) {
344                            const QModelIndex index = pRoutingModel->index(r, c);
345                            m_ui.audioRoutingTable->openPersistentEditor(index);
346                    }
347            }
348    }
349    
350  } // namespace QSampler  } // namespace QSampler
351    
352  // end of qsamplerChannelFxForm.cpp  // end of qsamplerChannelFxForm.cpp

Legend:
Removed from v.1667  
changed lines
  Added in v.1707

  ViewVC Help
Powered by ViewVC