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

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

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

revision 1463 by capela, Thu Nov 1 13:01:27 2007 UTC revision 1528 by capela, Mon Nov 26 18:24:38 2007 UTC
# Line 2  Line 2 
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5       Copyright (C) 2007, Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 19  Line 20 
20    
21  *****************************************************************************/  *****************************************************************************/
22    
 #include "qsamplerUtilities.h"  
23  #include "qsamplerAbout.h"  #include "qsamplerAbout.h"
24  #include "qsamplerChannel.h"  #include "qsamplerChannel.h"
25    #include "qsamplerUtilities.h"
26    
27  #include "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
28  #include "qsamplerChannelForm.h"  #include "qsamplerChannelForm.h"
29    
30  #include <qfileinfo.h>  #include <QFileInfo>
31  #include <qcombobox.h>  #include <QComboBox>
32    
33  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
34  #include "gig.h"  #include "gig.h"
# Line 35  Line 36 
36    
37  #define QSAMPLER_INSTRUMENT_MAX 100  #define QSAMPLER_INSTRUMENT_MAX 100
38    
39    #define UNICODE_RIGHT_ARROW     QChar(char(0x92), char(0x21))
40    
41    
42  using namespace QSampler;  using namespace QSampler;
43    
44  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
# Line 58  qsamplerChannel::qsamplerChannel ( int i Line 62  qsamplerChannel::qsamplerChannel ( int i
62          m_iMidiMap          = -1;          m_iMidiMap          = -1;
63          m_sAudioDriver      = "ALSA";          m_sAudioDriver      = "ALSA";
64          m_iAudioDevice      = -1;          m_iAudioDevice      = -1;
65          m_fVolume           = 0.0;          m_fVolume           = 0.0f;
66          m_bMute             = false;          m_bMute             = false;
67          m_bSolo             = false;          m_bSolo             = false;
68  }  }
# Line 155  bool qsamplerChannel::loadEngine ( const Line 159  bool qsamplerChannel::loadEngine ( const
159          if (m_iInstrumentStatus == 100 && m_sEngineName == sEngineName)          if (m_iInstrumentStatus == 100 && m_sEngineName == sEngineName)
160                  return true;                  return true;
161    
162          if (::lscp_load_engine(pMainForm->client(), sEngineName.latin1(), m_iChannelID) != LSCP_OK) {          if (::lscp_load_engine(pMainForm->client(),
163                            sEngineName.toUtf8().constData(), m_iChannelID) != LSCP_OK) {
164                  appendMessagesClient("lscp_load_engine");                  appendMessagesClient("lscp_load_engine");
165                  return false;                  return false;
166          }          }
# Line 207  bool qsamplerChannel::loadInstrument ( c Line 212  bool qsamplerChannel::loadInstrument ( c
212          if (          if (
213                  ::lscp_load_instrument_non_modal(                  ::lscp_load_instrument_non_modal(
214                          pMainForm->client(),                          pMainForm->client(),
215                          qsamplerUtilities::lscpEscapePath(sInstrumentFile).latin1(),                          qsamplerUtilities::lscpEscapePath(
216                                    sInstrumentFile).toUtf8().constData(),
217                          iInstrumentNr, m_iChannelID                          iInstrumentNr, m_iChannelID
218                  ) != LSCP_OK                  ) != LSCP_OK
219          ) {          ) {
# Line 254  bool qsamplerChannel::setMidiDriver ( co Line 260  bool qsamplerChannel::setMidiDriver ( co
260          if (m_iInstrumentStatus == 100 && m_sMidiDriver == sMidiDriver)          if (m_iInstrumentStatus == 100 && m_sMidiDriver == sMidiDriver)
261                  return true;                  return true;
262    
263          if (::lscp_set_channel_midi_type(pMainForm->client(), m_iChannelID, sMidiDriver.latin1()) != LSCP_OK) {          if (::lscp_set_channel_midi_type(pMainForm->client(),
264                            m_iChannelID, sMidiDriver.toUtf8().constData()) != LSCP_OK) {
265                  appendMessagesClient("lscp_set_channel_midi_type");                  appendMessagesClient("lscp_set_channel_midi_type");
266                  return false;                  return false;
267          }          }
# Line 422  bool qsamplerChannel::setAudioDriver ( c Line 429  bool qsamplerChannel::setAudioDriver ( c
429          if (m_iInstrumentStatus == 100 && m_sAudioDriver == sAudioDriver)          if (m_iInstrumentStatus == 100 && m_sAudioDriver == sAudioDriver)
430                  return true;                  return true;
431    
432          if (::lscp_set_channel_audio_type(pMainForm->client(), m_iChannelID, sAudioDriver.latin1()) != LSCP_OK) {          if (::lscp_set_channel_audio_type(pMainForm->client(),
433                            m_iChannelID, sAudioDriver.toUtf8().constData()) != LSCP_OK) {
434                  appendMessagesClient("lscp_set_channel_audio_type");                  appendMessagesClient("lscp_set_channel_audio_type");
435                  return false;                  return false;
436          }          }
# Line 699  bool qsamplerChannel::editChannel (void) Line 707  bool qsamplerChannel::editChannel (void)
707                  appendMessagesClient("lscp_edit_channel_instrument");                  appendMessagesClient("lscp_edit_channel_instrument");
708                  appendMessagesError(QObject::tr(                  appendMessagesError(QObject::tr(
709                          "Could not launch an appropriate instrument editor "                          "Could not launch an appropriate instrument editor "
710                          "for the given instrument!\n"                          "for the given instrument!\n\n"
711                          "Make sure you have an appropriate "                          "Make sure you have an appropriate "
712                          "instrument editor like 'gigedit' installed\n"                          "instrument editor like 'gigedit' installed "
713                          "and that it placed its mandatory DLL file "                          "and that it placed its mandatory DLL file "
714                          "into the sampler's plugin directory.")                          "into the sampler's plugin directory.")
715                  );                  );
# Line 716  bool qsamplerChannel::editChannel (void) Line 724  bool qsamplerChannel::editChannel (void)
724    
725          appendMessagesError(QObject::tr(          appendMessagesError(QObject::tr(
726                  "Sorry, QSampler was compiled for a version of liblscp "                  "Sorry, QSampler was compiled for a version of liblscp "
727                  "which lacks this feature.\n"                  "which lacks this feature.\n\n"
728                  "You may want to update liblscp and recompile QSampler afterwards.")                  "You may want to update liblscp and recompile QSampler afterwards.")
729          );          );
730    
# Line 801  bool qsamplerChannel::isInstrumentFile ( Line 809  bool qsamplerChannel::isInstrumentFile (
809          bool bResult = false;          bool bResult = false;
810    
811          QFile file(sInstrumentFile);          QFile file(sInstrumentFile);
812          if (file.open(IO_ReadOnly)) {          if (file.open(QIODevice::ReadOnly)) {
813                  char achHeader[16];                  char achHeader[16];
814                  if (file.readBlock(achHeader, 16)) {                  if (file.read(achHeader, 16) > 0) {
815                          bResult = (::memcmp(&achHeader[0], "RIFF", 4)     == 0                          bResult = (::memcmp(&achHeader[0], "RIFF", 4)     == 0
816                                          && ::memcmp(&achHeader[8], "DLS LIST", 8) == 0);                                          && ::memcmp(&achHeader[8], "DLS LIST", 8) == 0);
817                  }                  }
# Line 824  QStringList qsamplerChannel::getInstrume Line 832  QStringList qsamplerChannel::getInstrume
832          if (isInstrumentFile(sInstrumentFile)) {          if (isInstrumentFile(sInstrumentFile)) {
833  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
834                  if (bInstrumentNames) {                  if (bInstrumentNames) {
835                          RIFF::File *pRiff = new RIFF::File(sInstrumentFile.latin1());                          RIFF::File *pRiff
836                                    = new RIFF::File(sInstrumentFile.toUtf8().constData());
837                          gig::File  *pGig  = new gig::File(pRiff);                          gig::File  *pGig  = new gig::File(pRiff);
838    #if HAVE_LIBGIG_SETAUTOLOAD
839                            // prevent sleepy response time on large .gig files
840                            pGig->SetAutoLoad(false);
841    #endif
842                          gig::Instrument *pInstrument = pGig->GetFirstInstrument();                          gig::Instrument *pInstrument = pGig->GetFirstInstrument();
843                          while (pInstrument) {                          while (pInstrument) {
844                                  instlist.append((pInstrument->pInfo)->Name.c_str());                                  instlist.append((pInstrument->pInfo)->Name.c_str());
# Line 855  QString qsamplerChannel::getInstrumentNa Line 868  QString qsamplerChannel::getInstrumentNa
868                  sInstrumentName = QFileInfo(sInstrumentFile).fileName();                  sInstrumentName = QFileInfo(sInstrumentFile).fileName();
869  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
870                  if (bInstrumentNames) {                  if (bInstrumentNames) {
871                          RIFF::File *pRiff = new RIFF::File(sInstrumentFile.latin1());                          RIFF::File *pRiff
872                          gig::File  *pGig  = new gig::File(pRiff);                                  = new RIFF::File(sInstrumentFile.toUtf8().constData());
873                            gig::File *pGig = new gig::File(pRiff);
874    #if HAVE_LIBGIG_SETAUTOLOAD
875                            // prevent sleepy response time on large .gig files
876                            pGig->SetAutoLoad(false);
877    #endif
878                          int iIndex = 0;                          int iIndex = 0;
879                          gig::Instrument *pInstrument = pGig->GetFirstInstrument();                          gig::Instrument *pInstrument = pGig->GetFirstInstrument();
880                          while (pInstrument) {                          while (pInstrument) {
# Line 896  QString qsamplerChannel::loadingInstrume Line 914  QString qsamplerChannel::loadingInstrume
914  }  }
915    
916    
   
917  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
918  // qsamplerChannelRoutingTable - Channel routing table.  // ChannelRoutingModel - data model for audio routing (used for QTableView)
919  //  //
 #if 0  
 // Constructor.  
 qsamplerChannelRoutingTable::qsamplerChannelRoutingTable (  
         QWidget *pParent, const char *pszName )  
         : QTable(pParent, pszName)  
 {  
         // Set fixed number of columns.  
         QTable::setNumCols(2);  
         QTable::setShowGrid(false);  
         QTable::setSorting(false);  
         QTable::setFocusStyle(QTable::FollowStyle);  
         QTable::setSelectionMode(QTable::NoSelection);  
         // No vertical header.  
         QTable::verticalHeader()->hide();  
         QTable::setLeftMargin(0);  
         // Initialize the fixed table column headings.  
         QHeader *pHeader = QTable::horizontalHeader();  
         pHeader->setLabel(0, tr("Sampler Channel"));  
         pHeader->setLabel(1, tr("Device Channel"));  
         // Set read-onlyness of each column  
         QTable::setColumnReadOnly(0, true);  
 //      QTable::setColumnReadOnly(1, false); -- of course not.  
         QTable::setColumnStretchable(1, true);  
 }  
920    
921  // Default destructor.  ChannelRoutingModel::ChannelRoutingModel ( QObject *pParent )
922  qsamplerChannelRoutingTable::~qsamplerChannelRoutingTable (void)          : QAbstractTableModel(pParent), m_pDevice(NULL)
923  {  {
924  }  }
925    
926    
927  // Routing map table renderer.  int ChannelRoutingModel::rowCount ( const QModelIndex& /*parent*/) const
 void qsamplerChannelRoutingTable::refresh ( qsamplerDevice *pDevice,  
         const qsamplerChannelRoutingMap& routing )  
928  {  {
929          if (pDevice == NULL)          return m_routing.size();
                 return;  
   
         // Always (re)start it empty.  
         QTable::setUpdatesEnabled(false);  
         QTable::setNumRows(0);  
   
         // The common device port item list.  
         QStringList opts;  
         qsamplerDevicePortList& ports = pDevice->ports();  
         qsamplerDevicePort *pPort;  
         for (pPort = ports.first(); pPort; pPort = ports.next()) {  
                 opts.append(pDevice->deviceTypeName()  
                         + ' ' + pDevice->driverName()  
                         + ' ' + pPort->portName());  
         }  
   
         // Those items shall have a proper pixmap...  
         QPixmap pmChannel = QPixmap(":/icons/qsamplerChannel.png");  
         QPixmap pmDevice;  
         switch (pDevice->deviceType()) {  
         case qsamplerDevice::Audio:  
                 pmDevice = QPixmap(":/icons/audio2.png");  
                 break;  
         case qsamplerDevice::Midi:  
                 pmDevice = QPixmap(":/icons/midi2.png");  
                 break;  
         case qsamplerDevice::None:  
                 break;  
         }  
   
         // Fill the routing table...  
         QTable::insertRows(0, routing.count());  
         int iRow = 0;  
         qsamplerChannelRoutingMap::ConstIterator iter;  
         for (iter = routing.begin(); iter != routing.end(); ++iter) {  
                 QTable::setPixmap(iRow, 0, pmChannel);  
                 QTable::setText(iRow, 0, pDevice->deviceTypeName()  
                         + ' ' + QString::number(iter.key()));  
                 qsamplerChannelRoutingComboBox *pComboItem =  
                         new qsamplerChannelRoutingComboBox(this, opts, pmDevice);  
                 pComboItem->setCurrentItem(iter.data());  
                 QTable::setItem(iRow, 1, pComboItem);  
                 ++iRow;  
         }  
   
         // Adjust optimal column widths.  
         QTable::adjustColumn(0);  
         QTable::adjustColumn(1);  
   
         QTable::setUpdatesEnabled(true);  
         QTable::updateContents();  
930  }  }
931    
932    
933  // Commit any pending editing.  int ChannelRoutingModel::columnCount ( const QModelIndex& /*parent*/) const
 void qsamplerChannelRoutingTable::flush (void)  
934  {  {
935          if (QTable::isEditing())          return 1;
             QTable::endEdit(QTable::currEditRow(), QTable::currEditCol(), true, true);  
936  }  }
 #endif  
937    
 ChannelRoutingModel::ChannelRoutingModel(QObject* parent) : QAbstractTableModel(parent), pDevice(NULL) {  
 }  
938    
939  int ChannelRoutingModel::rowCount(const QModelIndex& /*parent*/) const {  Qt::ItemFlags ChannelRoutingModel::flags ( const QModelIndex& /*index*/) const
940      return routing.size();  {
941  }          return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
   
 int ChannelRoutingModel::columnCount(const QModelIndex& /*parent*/) const {  
     return 1;  
942  }  }
943    
 QVariant ChannelRoutingModel::data(const QModelIndex &index, int role) const {  
     if (!index.isValid())  
         return QVariant();  
     if (role != Qt::DisplayRole)  
         return QVariant();  
   
     ChannelRoutingItem item;  
944    
945      // The common device port item list.  bool ChannelRoutingModel::setData ( const QModelIndex& index,
946      qsamplerDevicePortList& ports = pDevice->ports();          const QVariant& value, int /*role*/)
947      qsamplerDevicePort* pPort;  {
948      for (pPort = ports.first(); pPort; pPort = ports.next()) {          if (!index.isValid())
949          item.options.append(                  return false;
             pDevice->deviceTypeName()  
             + ' ' + pDevice->driverName()  
             + ' ' + pPort->portName()  
         );  
     }  
950    
951      item.selection = routing[index.column()];          m_routing[index.row()] = value.toInt();
952    
953      return QVariant::fromValue(item);          emit dataChanged(index, index);
954            return true;
955  }  }
956    
 QVariant ChannelRoutingModel::headerData(int section, Qt::Orientation orientation, int role) const {  
     if (role != Qt::DisplayRole) return QVariant();  
   
     if (orientation == Qt::Horizontal)  
         return QObject::tr("Device Channel");  
   
     if (orientation == Qt::Vertical)  
         return QObject::tr("Sampler Channel Output ") +  
                QString(section);  
   
     return QVariant();  
 }  
957    
958  void ChannelRoutingModel::refresh ( qsamplerDevice *pDevice,  QVariant ChannelRoutingModel::data ( const QModelIndex &index, int role ) const
         const qsamplerChannelRoutingMap& routing )  
959  {  {
960      this->pDevice = pDevice;          if (!index.isValid())
961      this->routing = routing;                  return QVariant();
962  }          if (role != Qt::DisplayRole)
963                    return QVariant();
964            if (index.column() != 0)
965                    return QVariant();
966    
967            ChannelRoutingItem item;
968    
969            // The common device port item list.
970            qsamplerDevicePortList& ports = m_pDevice->ports();
971            QListIterator<qsamplerDevicePort *> iter(ports);
972            while (iter.hasNext()) {
973                    qsamplerDevicePort *pPort = iter.next();
974                    item.options.append(
975                            m_pDevice->deviceTypeName()
976                            + ' ' + m_pDevice->driverName()
977                            + ' ' + pPort->portName()
978                    );
979            }
980    
981            item.selection = m_routing[index.row()];
982    
983  ChannelRoutingDelegate::ChannelRoutingDelegate(QObject *parent) : QItemDelegate(parent) {          return QVariant::fromValue(item);
984  }  }
985    
 QWidget* ChannelRoutingDelegate::createEditor(QWidget *parent,  
         const QStyleOptionViewItem &/* option */,  
         const QModelIndex& index) const  
 {  
     ChannelRoutingItem item = index.model()->data(index, Qt::DisplayRole).value<ChannelRoutingItem>();  
986    
987      QComboBox* editor = new QComboBox(parent);  QVariant ChannelRoutingModel::headerData ( int section,
988      editor->addItems(item.options);          Qt::Orientation orientation, int role) const
989      editor->setCurrentIndex(item.selection);  {
990      editor->installEventFilter(const_cast<ChannelRoutingDelegate*>(this));          if (role != Qt::DisplayRole)
991      return editor;                  return QVariant();
 }  
992    
993  void ChannelRoutingDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {          switch (orientation) {
994      ChannelRoutingItem item = index.model()->data(index, Qt::DisplayRole).value<ChannelRoutingItem>();                  case Qt::Horizontal:
995      QComboBox* comboBox = static_cast<QComboBox*>(editor);                          return UNICODE_RIGHT_ARROW + QObject::tr(" Device Channel");
996      comboBox->setCurrentIndex(item.selection);                  case Qt::Vertical:
997                            return QObject::tr("Sampler Channel ") +
998                                    QString::number(section) + " " + UNICODE_RIGHT_ARROW;
999                    default:
1000                            return QVariant();
1001            }
1002  }  }
1003    
 void ChannelRoutingDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {  
     QComboBox* comboBox = static_cast<QComboBox*>(editor);  
     model->setData(index, comboBox->currentIndex());  
 }  
1004    
1005  void ChannelRoutingDelegate::updateEditorGeometry(QWidget *editor,  void ChannelRoutingModel::refresh ( qsamplerDevice *pDevice,
1006          const QStyleOptionViewItem &option, const QModelIndex &/* index */) const          const qsamplerChannelRoutingMap& routing )
1007  {  {
1008      editor->setGeometry(option.rect);          m_pDevice = pDevice;
1009            m_routing = routing;
1010            // inform the outer world (QTableView) that our data changed
1011            QAbstractTableModel::reset();
1012  }  }
1013    
1014    
   
1015  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1016  // qsamplerChannelRoutingComboBox - Custom combo box for routing table.  // ChannelRoutingDelegate - table cell renderer for audio routing
1017  //  //
1018    
1019  #if 0  ChannelRoutingDelegate::ChannelRoutingDelegate ( QObject *pParent )
1020  // Constructor.          : QItemDelegate(pParent)
 qsamplerChannelRoutingComboBox::qsamplerChannelRoutingComboBox (  
         QTable *pTable, const QStringList& list, const QPixmap& pixmap )  
         : QTableItem(pTable, QTableItem::WhenCurrent, QString::null, pixmap),  
         m_list(list)  
1021  {  {
         m_iCurrentItem = 0;  
1022  }  }
1023    
1024  // Public accessors.  
1025  void qsamplerChannelRoutingComboBox::setCurrentItem ( int iCurrentItem )  QWidget* ChannelRoutingDelegate::createEditor ( QWidget *pParent,
1026            const QStyleOptionViewItem & option, const QModelIndex& index ) const
1027  {  {
1028          m_iCurrentItem = iCurrentItem;          if (!index.isValid())
1029                    return NULL;
1030    
1031            if (index.column() != 0)
1032                    return NULL;
1033    
1034            ChannelRoutingItem item = index.model()->data(index, Qt::DisplayRole).value<ChannelRoutingItem>();
1035    
1036          QTableItem::setText(m_list[iCurrentItem]);          QComboBox* pComboBox = new QComboBox(pParent);
1037            pComboBox->addItems(item.options);
1038            pComboBox->setCurrentIndex(item.selection);
1039            pComboBox->setEnabled(true);
1040            pComboBox->setGeometry(option.rect);
1041            return pComboBox;
1042  }  }
1043    
1044  int qsamplerChannelRoutingComboBox::currentItem (void) const  
1045    void ChannelRoutingDelegate::setEditorData ( QWidget *pEditor,
1046            const QModelIndex &index) const
1047  {  {
1048          return m_iCurrentItem;          ChannelRoutingItem item = index.model()->data(index,
1049                    Qt::DisplayRole).value<ChannelRoutingItem> ();
1050            QComboBox* pComboBox = static_cast<QComboBox*> (pEditor);
1051            pComboBox->setCurrentIndex(item.selection);
1052  }  }
1053    
1054  // Virtual implemetations.  
1055  QWidget *qsamplerChannelRoutingComboBox::createEditor (void) const  void ChannelRoutingDelegate::setModelData ( QWidget* pEditor,
1056            QAbstractItemModel *pModel, const QModelIndex& index ) const
1057  {  {
1058          QComboBox *pComboBox = new QComboBox(QTableItem::table()->viewport());          QComboBox *pComboBox = static_cast<QComboBox*> (pEditor);
1059          QObject::connect(pComboBox, SIGNAL(activated(int)),          pModel->setData(index, pComboBox->currentIndex());
                 QTableItem::table(), SLOT(doValueChanged()));  
         for (QStringList::ConstIterator iter = m_list.begin();  
                         iter != m_list.end(); iter++) {  
                 pComboBox->insertItem(QTableItem::pixmap(), *iter);  
         }  
         pComboBox->setCurrentItem(m_iCurrentItem);  
         return pComboBox;  
1060  }  }
1061    
1062  void qsamplerChannelRoutingComboBox::setContentFromEditor ( QWidget *pWidget )  
1063    void ChannelRoutingDelegate::updateEditorGeometry ( QWidget *pEditor,
1064            const QStyleOptionViewItem& option, const QModelIndex &/* index */) const
1065  {  {
1066          if (pWidget->inherits("QComboBox")) {          pEditor->setGeometry(option.rect);
                 QComboBox *pComboBox = (QComboBox *) pWidget;  
                 m_iCurrentItem = pComboBox->currentItem();  
                 QTableItem::setText(pComboBox->currentText());  
         }  
         else QTableItem::setContentFromEditor(pWidget);  
1067  }  }
1068    
1069  #endif  
1070    // end of qsamplerChannel.cpp

Legend:
Removed from v.1463  
changed lines
  Added in v.1528

  ViewVC Help
Powered by ViewVC