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

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

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

revision 3358 by capela, Wed Oct 18 08:57:21 2017 UTC revision 3508 by capela, Mon Apr 1 22:36:26 2019 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2017, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007,2008,2015 Christian Schoenebeck     Copyright (C) 2007,2008,2015 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
# Line 109  static WSADATA _wsaData; Line 109  static WSADATA _wsaData;
109  #include <signal.h>  #include <signal.h>
110    
111  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
112  static int g_fdUsr1[2];  static int g_fdSigusr1[2];
113    
114  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
115  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
116  {  {
117          char c = 1;          char c = 1;
118    
119          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
120    }
121    
122    // File descriptor for SIGTERM notifier.
123    static int g_fdSigterm[2];
124    
125    // Unix SIGTERM signal handler.
126    static void qsampler_sigterm_handler ( int /* signo */ )
127    {
128            char c = 1;
129    
130            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
131  }  }
132    
133  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
# Line 233  MainForm::MainForm ( QWidget *pParent ) Line 244  MainForm::MainForm ( QWidget *pParent )
244          // LADISH Level 1 suport.          // LADISH Level 1 suport.
245    
246          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
247          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
248          m_pUsr1Notifier          m_pSigusr1Notifier
249                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
250    
251          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
252                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
253                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
254    
255          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
256      struct sigaction usr1;      struct sigaction sigusr1;
257      usr1.sa_handler = qsampler_sigusr1_handler;      sigusr1.sa_handler = qsampler_sigusr1_handler;
258      sigemptyset(&usr1.sa_mask);      sigemptyset(&sigusr1.sa_mask);
259      usr1.sa_flags = 0;      sigusr1.sa_flags = 0;
260      usr1.sa_flags |= SA_RESTART;      sigusr1.sa_flags |= SA_RESTART;
261      ::sigaction(SIGUSR1, &usr1, NULL);      ::sigaction(SIGUSR1, &sigusr1, NULL);
262    
263            // Initialize file descriptors for SIGTERM socket notifier.
264            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
265            m_pSigtermNotifier
266                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
267    
268            QObject::connect(m_pSigtermNotifier,
269                    SIGNAL(activated(int)),
270                    SLOT(handle_sigterm()));
271    
272            // Install SIGTERM signal handler.
273            struct sigaction sigterm;
274            sigterm.sa_handler = qsampler_sigterm_handler;
275            ::sigemptyset(&sigterm.sa_mask);
276            sigterm.sa_flags = 0;
277            sigterm.sa_flags |= SA_RESTART;
278            ::sigaction(SIGTERM, &sigterm, NULL);
279            ::sigaction(SIGQUIT, &sigterm, NULL);
280    
281            // Ignore SIGHUP/SIGINT signals.
282            ::signal(SIGHUP, SIG_IGN);
283            ::signal(SIGINT, SIG_IGN);
284    
285  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
286    
287          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = NULL;
288            m_pSigtermNotifier = NULL;
289                    
290  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
291    
# Line 430  MainForm::~MainForm() Line 464  MainForm::~MainForm()
464  #endif  #endif
465    
466  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
467          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
468                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
469            if (m_pSigtermNotifier)
470                    delete m_pSigtermNotifier;
471  #endif  #endif
472    
473          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 721  void MainForm::handle_sigusr1 (void) Line 757  void MainForm::handle_sigusr1 (void)
757    
758          char c;          char c;
759    
760          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
761                  saveSession(false);                  saveSession(false);
762    
763  #endif  #endif
764  }  }
765    
766    
767    void MainForm::handle_sigterm (void)
768    {
769    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
770    
771            char c;
772    
773            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
774                    close();
775    
776    #endif
777    }
778    
779    
780  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
781  {  {
782          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 866  bool MainForm::saveSession ( bool bPromp Line 915  bool MainForm::saveSession ( bool bPromp
915                  // Enforce .lscp extension...                  // Enforce .lscp extension...
916                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
917                          sFilename += ".lscp";                          sFilename += ".lscp";
918            #if 0
919                  // Check if already exists...                  // Check if already exists...
920                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
921                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
# Line 878  bool MainForm::saveSession ( bool bPromp Line 928  bool MainForm::saveSession ( bool bPromp
928                                  == QMessageBox::No)                                  == QMessageBox::No)
929                                  return false;                                  return false;
930                  }                  }
931            #endif
932          }          }
933    
934          // Save it right away.          // Save it right away.
# Line 1060  bool MainForm::saveSessionFile ( const Q Line 1111  bool MainForm::saveSessionFile ( const Q
1111          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1112          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1113          int *piDeviceIDs;          int *piDeviceIDs;
1114          int  iDevice;          int  i, iDevice;
1115          ts << "RESET" << endl;          ts << "RESET" << endl;
1116    
1117          // Audio device mapping.          // Audio device mapping.
1118          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1119          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1120          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1121                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1122                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1123                    if (device.driverName().toUpper() == "PLUGIN")
1124                            continue;
1125                  // Audio device specification...                  // Audio device specification...
1126                    ts << endl;
1127                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1128                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1129                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1100  bool MainForm::saveSessionFile ( const Q Line 1154  bool MainForm::saveSessionFile ( const Q
1154                          iPort++;                          iPort++;
1155                  }                  }
1156                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1157                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1158                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1159                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1160          }          }
1161    
1162          // MIDI device mapping.          // MIDI device mapping.
1163          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1164          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1165          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1166                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1167                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1168                    if (device.driverName().toUpper() == "PLUGIN")
1169                            continue;
1170                  // MIDI device specification...                  // MIDI device specification...
1171                    ts << endl;
1172                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1173                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1174                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1142  bool MainForm::saveSessionFile ( const Q Line 1199  bool MainForm::saveSessionFile ( const Q
1199                          iPort++;                          iPort++;
1200                  }                  }
1201                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1202                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1203                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1204                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1205          }          }
# Line 1210  bool MainForm::saveSessionFile ( const Q Line 1267  bool MainForm::saveSessionFile ( const Q
1267                          iErrors++;                          iErrors++;
1268                  }                  }
1269                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1270                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1271          }          }
1272          // Check for errors...          // Check for errors...
1273          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {          if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
# Line 1219  bool MainForm::saveSessionFile ( const Q Line 1276  bool MainForm::saveSessionFile ( const Q
1276          }          }
1277  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1278    
1279          // Sampler channel mapping.          // Sampler channel mapping...
1280            int iChannelID = 0;
1281          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1282                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1283          const int iStripCount = wlist.count();          const int iStripCount = wlist.count();
# Line 1231  bool MainForm::saveSessionFile ( const Q Line 1289  bool MainForm::saveSessionFile ( const Q
1289                  if (pChannelStrip) {                  if (pChannelStrip) {
1290                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1291                          if (pChannel) {                          if (pChannel) {
1292                                  const int iChannelID = pChannel->channelID();                                  // Avoid "artifial" plug-in devices...
1293                                    const int iAudioDevice = pChannel->audioDevice();
1294                                    if (!audioDeviceMap.contains(iAudioDevice))
1295                                            continue;
1296                                    const int iMidiDevice = pChannel->midiDevice();
1297                                    if (!midiDeviceMap.contains(iMidiDevice))
1298                                            continue;
1299                                    // Go for regular, canonical devices...
1300                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;
1301                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1302                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
# Line 1239  bool MainForm::saveSessionFile ( const Q Line 1304  bool MainForm::saveSessionFile ( const Q
1304                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1305                                  } else {                                  } else {
1306                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1307                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1308                                  }                                  }
1309                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1310                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1311                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1312                                  } else {                                  } else {
1313                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1314                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1315                                  }                                  }
1316                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1317                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
# Line 1277  bool MainForm::saveSessionFile ( const Q Line 1342  bool MainForm::saveSessionFile ( const Q
1342                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1343                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1344                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1345                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1346                                    if (midiInstrumentMap.contains(iMidiMap)) {
1347                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1348                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap.value(iMidiMap) << endl;
1349                                  }                                  }
1350                          #endif                          #endif
1351                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
# Line 1318  bool MainForm::saveSessionFile ( const Q Line 1384  bool MainForm::saveSessionFile ( const Q
1384                                  }                                  }
1385                          #endif                          #endif
1386                                  ts << endl;                                  ts << endl;
1387                                    // Go for next channel...
1388                                    ++iChannelID;
1389                          }                          }
1390                  }                  }
1391                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 2864  void MainForm::stopServer ( bool bIntera Line 2932  void MainForm::stopServer ( bool bIntera
2932                  }                  }
2933          }          }
2934    
2935            bool bGraceWait = true;
2936    
2937          // And try to stop server.          // And try to stop server.
2938          if (m_pServer && m_bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2939                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
# Line 2874  void MainForm::stopServer ( bool bIntera Line 2944  void MainForm::stopServer ( bool bIntera
2944                  #else                  #else
2945                          // Try softly...                          // Try softly...
2946                          m_pServer->terminate();                          m_pServer->terminate();
2947                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2948                            if (bFinished) bGraceWait = false;
2949                  #endif                  #endif
2950                  }                  }
2951          }       // Do final processing anyway.          }       // Do final processing anyway.
2952          else processServerExit();          else processServerExit();
2953    
2954          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2955          QTime t;          if (bGraceWait) {
2956          t.start();                  QTime t;
2957          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  t.start();
2958                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2959                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2960            }
2961  }  }
2962    
2963    

Legend:
Removed from v.3358  
changed lines
  Added in v.3508

  ViewVC Help
Powered by ViewVC