/[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 3049 by capela, Sat Dec 3 09:47:38 2016 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-2016, 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 91  static inline long lroundf ( float x ) Line 91  static inline long lroundf ( float x )
91    
92    
93  // All winsock apps needs this.  // All winsock apps needs this.
94  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
95  static WSADATA _wsaData;  static WSADATA _wsaData;
96  #endif  #endif
97    
# 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 324  MainForm::MainForm ( QWidget *pParent ) Line 358  MainForm::MainForm ( QWidget *pParent )
358          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;          m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
359          statusBar()->addWidget(pLabel);          statusBar()->addWidget(pLabel);
360    
361  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
362          WSAStartup(MAKEWORD(1, 1), &_wsaData);          WSAStartup(MAKEWORD(1, 1), &_wsaData);
363  #endif  #endif
364    
# Line 425  MainForm::~MainForm() Line 459  MainForm::~MainForm()
459          // Do final processing anyway.          // Do final processing anyway.
460          processServerExit();          processServerExit();
461    
462  #if defined(WIN32)  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
463          WSACleanup();          WSACleanup();
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 2801  void MainForm::startServer (void) Line 2869  void MainForm::startServer (void)
2869    
2870          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2871          m_pServer = new QProcess();          m_pServer = new QProcess();
2872          bForceServerStop = true;          m_bForceServerStop = true;
2873    
2874          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2875          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);          m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
# Line 2845  void MainForm::startServer (void) Line 2913  void MainForm::startServer (void)
2913    
2914    
2915  // Stop linuxsampler server...  // Stop linuxsampler server...
2916  void MainForm::stopServer (bool bInteractive)  void MainForm::stopServer ( bool bInteractive )
2917  {  {
2918          // Stop client code.          // Stop client code.
2919          stopClient();          stopClient();
# Line 2859  void MainForm::stopServer (bool bInterac Line 2927  void MainForm::stopServer (bool bInterac
2927                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2928                          "Do you want LinuxSampler to stop?"),                          "Do you want LinuxSampler to stop?"),
2929                          QMessageBox::Yes | QMessageBox::No,                          QMessageBox::Yes | QMessageBox::No,
2930                          QMessageBox::Yes) == QMessageBox::No)                          QMessageBox::Yes) == QMessageBox::No) {
2931                  {                          m_bForceServerStop = false;
                         bForceServerStop = false;  
2932                  }                  }
2933          }          }
2934    
2935            bool bGraceWait = true;
2936    
2937          // And try to stop server.          // And try to stop server.
2938          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2939                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2940                  if (m_pServer->state() == QProcess::Running) {                  if (m_pServer->state() == QProcess::Running) {
2941                  #if defined(WIN32)                  #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
2942                          // Try harder...                          // Try harder...
2943                          m_pServer->kill();                          m_pServer->kill();
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    
# Line 2906  void MainForm::processServerExit (void) Line 2979  void MainForm::processServerExit (void)
2979          if (m_pMessages)          if (m_pMessages)
2980                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2981    
2982          if (m_pServer && bForceServerStop) {          if (m_pServer && m_bForceServerStop) {
2983                  if (m_pServer->state() != QProcess::NotRunning) {                  if (m_pServer->state() != QProcess::NotRunning) {
2984                          appendMessages(tr("Server is being forced..."));                          appendMessages(tr("Server is being forced..."));
2985                          // Force final server shutdown...                          // Force final server shutdown...
# Line 2983  bool MainForm::startClient (void) Line 3056  bool MainForm::startClient (void)
3056                  stabilizeForm();                  stabilizeForm();
3057                  return false;                  return false;
3058          }          }
3059    
3060          // Just set receive timeout value, blindly.          // Just set receive timeout value, blindly.
3061          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);          ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
3062          appendMessages(          appendMessages(

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

  ViewVC Help
Powered by ViewVC