/[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 3509 by capela, Tue Apr 2 17:55:00 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 68  const WindowFlags WindowCloseButtonHint Line 68  const WindowFlags WindowCloseButtonHint
68  }  }
69  #endif  #endif
70    
 #ifdef HAVE_SIGNAL_H  
 #include <signal.h>  
 #endif  
   
71  #ifdef CONFIG_LIBGIG  #ifdef CONFIG_LIBGIG
72  #include <gig.h>  #include <gig.h>
73  #endif  #endif
# Line 109  static WSADATA _wsaData; Line 105  static WSADATA _wsaData;
105  #include <signal.h>  #include <signal.h>
106    
107  // File descriptor for SIGUSR1 notifier.  // File descriptor for SIGUSR1 notifier.
108  static int g_fdUsr1[2];  static int g_fdSigusr1[2];
109    
110  // Unix SIGUSR1 signal handler.  // Unix SIGUSR1 signal handler.
111  static void qsampler_sigusr1_handler ( int /* signo */ )  static void qsampler_sigusr1_handler ( int /* signo */ )
112  {  {
113          char c = 1;          char c = 1;
114    
115          (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);          (::write(g_fdSigusr1[0], &c, sizeof(c)) > 0);
116    }
117    
118    // File descriptor for SIGTERM notifier.
119    static int g_fdSigterm[2];
120    
121    // Unix SIGTERM signal handler.
122    static void qsampler_sigterm_handler ( int /* signo */ )
123    {
124            char c = 1;
125    
126            (::write(g_fdSigterm[0], &c, sizeof(c)) > 0);
127  }  }
128    
129  #endif  // HAVE_SIGNAL_H  #endif  // HAVE_SIGNAL_H
# Line 233  MainForm::MainForm ( QWidget *pParent ) Line 240  MainForm::MainForm ( QWidget *pParent )
240          // LADISH Level 1 suport.          // LADISH Level 1 suport.
241    
242          // Initialize file descriptors for SIGUSR1 socket notifier.          // Initialize file descriptors for SIGUSR1 socket notifier.
243          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);          ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigusr1);
244          m_pUsr1Notifier          m_pSigusr1Notifier
245                  = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);                  = new QSocketNotifier(g_fdSigusr1[1], QSocketNotifier::Read, this);
246    
247          QObject::connect(m_pUsr1Notifier,          QObject::connect(m_pSigusr1Notifier,
248                  SIGNAL(activated(int)),                  SIGNAL(activated(int)),
249                  SLOT(handle_sigusr1()));                  SLOT(handle_sigusr1()));
250    
251          // Install SIGUSR1 signal handler.          // Install SIGUSR1 signal handler.
252      struct sigaction usr1;      struct sigaction sigusr1;
253      usr1.sa_handler = qsampler_sigusr1_handler;      sigusr1.sa_handler = qsampler_sigusr1_handler;
254      sigemptyset(&usr1.sa_mask);      sigemptyset(&sigusr1.sa_mask);
255      usr1.sa_flags = 0;      sigusr1.sa_flags = 0;
256      usr1.sa_flags |= SA_RESTART;      sigusr1.sa_flags |= SA_RESTART;
257      ::sigaction(SIGUSR1, &usr1, NULL);      ::sigaction(SIGUSR1, &sigusr1, NULL);
258    
259            // Initialize file descriptors for SIGTERM socket notifier.
260            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdSigterm);
261            m_pSigtermNotifier
262                    = new QSocketNotifier(g_fdSigterm[1], QSocketNotifier::Read, this);
263    
264            QObject::connect(m_pSigtermNotifier,
265                    SIGNAL(activated(int)),
266                    SLOT(handle_sigterm()));
267    
268            // Install SIGTERM signal handler.
269            struct sigaction sigterm;
270            sigterm.sa_handler = qsampler_sigterm_handler;
271            ::sigemptyset(&sigterm.sa_mask);
272            sigterm.sa_flags = 0;
273            sigterm.sa_flags |= SA_RESTART;
274            ::sigaction(SIGTERM, &sigterm, NULL);
275            ::sigaction(SIGQUIT, &sigterm, NULL);
276    
277            // Ignore SIGHUP/SIGINT signals.
278            ::signal(SIGHUP, SIG_IGN);
279            ::signal(SIGINT, SIG_IGN);
280    
281  #else   // HAVE_SIGNAL_H  #else   // HAVE_SIGNAL_H
282    
283          m_pUsr1Notifier = NULL;          m_pSigusr1Notifier = NULL;
284            m_pSigtermNotifier = NULL;
285                    
286  #endif  // !HAVE_SIGNAL_H  #endif  // !HAVE_SIGNAL_H
287    
# Line 430  MainForm::~MainForm() Line 460  MainForm::~MainForm()
460  #endif  #endif
461    
462  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)  #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
463          if (m_pUsr1Notifier)          if (m_pSigusr1Notifier)
464                  delete m_pUsr1Notifier;                  delete m_pSigusr1Notifier;
465            if (m_pSigtermNotifier)
466                    delete m_pSigtermNotifier;
467  #endif  #endif
468    
469          // Finally drop any widgets around...          // Finally drop any widgets around...
# Line 721  void MainForm::handle_sigusr1 (void) Line 753  void MainForm::handle_sigusr1 (void)
753    
754          char c;          char c;
755    
756          if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)          if (::read(g_fdSigusr1[1], &c, sizeof(c)) > 0)
757                  saveSession(false);                  saveSession(false);
758    
759  #endif  #endif
760  }  }
761    
762    
763    void MainForm::handle_sigterm (void)
764    {
765    #if defined(HAVE_SIGNAL_H) && defined(HAVE_SYS_SOCKET_H)
766    
767            char c;
768    
769            if (::read(g_fdSigterm[1], &c, sizeof(c)) > 0)
770                    close();
771    
772    #endif
773    }
774    
775    
776  void MainForm::updateViewMidiDeviceStatusMenu (void)  void MainForm::updateViewMidiDeviceStatusMenu (void)
777  {  {
778          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
# Line 866  bool MainForm::saveSession ( bool bPromp Line 911  bool MainForm::saveSession ( bool bPromp
911                  // Enforce .lscp extension...                  // Enforce .lscp extension...
912                  if (QFileInfo(sFilename).suffix().isEmpty())                  if (QFileInfo(sFilename).suffix().isEmpty())
913                          sFilename += ".lscp";                          sFilename += ".lscp";
914            #if 0
915                  // Check if already exists...                  // Check if already exists...
916                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {                  if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
917                          if (QMessageBox::warning(this,                          if (QMessageBox::warning(this,
# Line 878  bool MainForm::saveSession ( bool bPromp Line 924  bool MainForm::saveSession ( bool bPromp
924                                  == QMessageBox::No)                                  == QMessageBox::No)
925                                  return false;                                  return false;
926                  }                  }
927            #endif
928          }          }
929    
930          // Save it right away.          // Save it right away.
# Line 1060  bool MainForm::saveSessionFile ( const Q Line 1107  bool MainForm::saveSessionFile ( const Q
1107          // It is assumed that this new kind of device+session file          // It is assumed that this new kind of device+session file
1108          // will be loaded from a complete initialized server...          // will be loaded from a complete initialized server...
1109          int *piDeviceIDs;          int *piDeviceIDs;
1110          int  iDevice;          int  i, iDevice;
1111          ts << "RESET" << endl;          ts << "RESET" << endl;
1112    
1113          // Audio device mapping.          // Audio device mapping.
1114          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap; iDevice = 0;
1115          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
1116          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1117                  ts << endl;                  Device device(Device::Audio, piDeviceIDs[i]);
1118                  Device device(Device::Audio, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1119                    if (device.driverName().toUpper() == "PLUGIN")
1120                            continue;
1121                  // Audio device specification...                  // Audio device specification...
1122                    ts << endl;
1123                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1124                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1125                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
# Line 1100  bool MainForm::saveSessionFile ( const Q Line 1150  bool MainForm::saveSessionFile ( const Q
1150                          iPort++;                          iPort++;
1151                  }                  }
1152                  // Audio device index/id mapping.                  // Audio device index/id mapping.
1153                  audioDeviceMap[device.deviceID()] = iDevice;                  audioDeviceMap.insert(device.deviceID(), iDevice++);
1154                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1155                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1156          }          }
1157    
1158          // MIDI device mapping.          // MIDI device mapping.
1159          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap; iDevice = 0;
1160          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
1161          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; ++i) {
1162                  ts << endl;                  Device device(Device::Midi, piDeviceIDs[i]);
1163                  Device device(Device::Midi, piDeviceIDs[iDevice]);                  // Avoid plug-in driver devices...
1164                    if (device.driverName().toUpper() == "PLUGIN")
1165                            continue;
1166                  // MIDI device specification...                  // MIDI device specification...
1167                    ts << endl;
1168                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
1169                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
1170                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
# Line 1142  bool MainForm::saveSessionFile ( const Q Line 1195  bool MainForm::saveSessionFile ( const Q
1195                          iPort++;                          iPort++;
1196                  }                  }
1197                  // MIDI device index/id mapping.                  // MIDI device index/id mapping.
1198                  midiDeviceMap[device.deviceID()] = iDevice;                  midiDeviceMap.insert(device.deviceID(), iDevice++);
1199                  // Try to keep it snappy :)                  // Try to keep it snappy :)
1200                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1201          }          }
# Line 1210  bool MainForm::saveSessionFile ( const Q Line 1263  bool MainForm::saveSessionFile ( const Q
1263                          iErrors++;                          iErrors++;
1264                  }                  }
1265                  // MIDI strument index/id mapping.                  // MIDI strument index/id mapping.
1266                  midiInstrumentMap[iMidiMap] = iMap;                  midiInstrumentMap.insert(iMidiMap, iMap);
1267          }          }
1268          // Check for errors...          // Check for errors...
1269          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 1272  bool MainForm::saveSessionFile ( const Q
1272          }          }
1273  #endif  // CONFIG_MIDI_INSTRUMENT  #endif  // CONFIG_MIDI_INSTRUMENT
1274    
1275          // Sampler channel mapping.          // Sampler channel mapping...
1276            int iChannelID = 0;
1277          const QList<QMdiSubWindow *>& wlist          const QList<QMdiSubWindow *>& wlist
1278                  = m_pWorkspace->subWindowList();                  = m_pWorkspace->subWindowList();
1279          const int iStripCount = wlist.count();          const int iStripCount = wlist.count();
# Line 1231  bool MainForm::saveSessionFile ( const Q Line 1285  bool MainForm::saveSessionFile ( const Q
1285                  if (pChannelStrip) {                  if (pChannelStrip) {
1286                          Channel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1287                          if (pChannel) {                          if (pChannel) {
1288                                  const int iChannelID = pChannel->channelID();                                  // Avoid "artifial" plug-in devices...
1289                                    const int iAudioDevice = pChannel->audioDevice();
1290                                    if (!audioDeviceMap.contains(iAudioDevice))
1291                                            continue;
1292                                    const int iMidiDevice = pChannel->midiDevice();
1293                                    if (!midiDeviceMap.contains(iMidiDevice))
1294                                            continue;
1295                                    // Go for regular, canonical devices...
1296                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;                                  ts << "# " << tr("Channel") << " " << iChannelID << endl;
1297                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
1298                                  if (audioDeviceMap.isEmpty()) {                                  if (audioDeviceMap.isEmpty()) {
# Line 1239  bool MainForm::saveSessionFile ( const Q Line 1300  bool MainForm::saveSessionFile ( const Q
1300                                                  << " " << pChannel->audioDriver() << endl;                                                  << " " << pChannel->audioDriver() << endl;
1301                                  } else {                                  } else {
1302                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannelID
1303                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;                                                  << " " << audioDeviceMap.value(iAudioDevice) << endl;
1304                                  }                                  }
1305                                  if (midiDeviceMap.isEmpty()) {                                  if (midiDeviceMap.isEmpty()) {
1306                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID
1307                                                  << " " << pChannel->midiDriver() << endl;                                                  << " " << pChannel->midiDriver() << endl;
1308                                  } else {                                  } else {
1309                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID                                          ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannelID
1310                                                  << " " << midiDeviceMap[pChannel->midiDevice()] << endl;                                                  << " " << midiDeviceMap.value(iMidiDevice) << endl;
1311                                  }                                  }
1312                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID                                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID
1313                                          << " " << pChannel->midiPort() << endl;                                          << " " << pChannel->midiPort() << endl;
# Line 1277  bool MainForm::saveSessionFile ( const Q Line 1338  bool MainForm::saveSessionFile ( const Q
1338                                  if (pChannel->channelSolo())                                  if (pChannel->channelSolo())
1339                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;                                          ts << "SET CHANNEL SOLO " << iChannelID << " 1" << endl;
1340                          #ifdef CONFIG_MIDI_INSTRUMENT                          #ifdef CONFIG_MIDI_INSTRUMENT
1341                                  if (pChannel->midiMap() >= 0) {                                  const int iMidiMap = pChannel->midiMap();
1342                                    if (midiInstrumentMap.contains(iMidiMap)) {
1343                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID                                          ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannelID
1344                                                  << " " << midiInstrumentMap[pChannel->midiMap()] << endl;                                                  << " " << midiInstrumentMap.value(iMidiMap) << endl;
1345                                  }                                  }
1346                          #endif                          #endif
1347                          #ifdef CONFIG_FXSEND                          #ifdef CONFIG_FXSEND
# Line 1318  bool MainForm::saveSessionFile ( const Q Line 1380  bool MainForm::saveSessionFile ( const Q
1380                                  }                                  }
1381                          #endif                          #endif
1382                                  ts << endl;                                  ts << endl;
1383                                    // Go for next channel...
1384                                    ++iChannelID;
1385                          }                          }
1386                  }                  }
1387                  // Try to keep it snappy :)                  // Try to keep it snappy :)
# Line 2864  void MainForm::stopServer ( bool bIntera Line 2928  void MainForm::stopServer ( bool bIntera
2928                  }                  }
2929          }          }
2930    
2931            bool bGraceWait = true;
2932    
2933          // And try to stop server.          // And try to stop server.
2934          if (m_pServer && m_bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2935                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
# Line 2874  void MainForm::stopServer ( bool bIntera Line 2940  void MainForm::stopServer ( bool bIntera
2940                  #else                  #else
2941                          // Try softly...                          // Try softly...
2942                          m_pServer->terminate();                          m_pServer->terminate();
2943                            bool bFinished = m_pServer->waitForFinished(QSAMPLER_TIMER_MSECS * 1000);
2944                            if (bFinished) bGraceWait = false;
2945                  #endif                  #endif
2946                  }                  }
2947          }       // Do final processing anyway.          }       // Do final processing anyway.
2948          else processServerExit();          else processServerExit();
2949    
2950          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2951          QTime t;          if (bGraceWait) {
2952          t.start();                  QTime t;
2953          while (t.elapsed() < QSAMPLER_TIMER_MSECS)                  t.start();
2954                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2955                            QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2956            }
2957  }  }
2958    
2959    

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

  ViewVC Help
Powered by ViewVC