/[svn]/linuxsampler/trunk/src/network/lscpserver.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/network/lscpserver.cpp

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

revision 2427 by persson, Sat Mar 2 07:03:04 2013 UTC revision 2515 by schoenebeck, Wed Feb 5 20:45:18 2014 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 - 2013 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2014 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This library is free software; you can redistribute it and/or modify  *   *   This library is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 47  Line 47 
47    
48  namespace LinuxSampler {  namespace LinuxSampler {
49    
50    String lscpParserProcessShellInteraction(String& line, yyparse_param_t* param);
51    
52  /**  /**
53   * Returns a copy of the given string where all special characters are   * Returns a copy of the given string where all special characters are
54   * replaced by LSCP escape sequences ("\xHH"). This function shall be used   * replaced by LSCP escape sequences ("\xHH"). This function shall be used
# Line 592  int LSCPServer::Main() { Line 594  int LSCPServer::Main() {
594          //Something was selected and it was not the hSocket, so it must be some command(s) coming.          //Something was selected and it was not the hSocket, so it must be some command(s) coming.
595          for (std::vector<yyparse_param_t>::iterator iter = Sessions.begin(); iter != Sessions.end(); iter++) {          for (std::vector<yyparse_param_t>::iterator iter = Sessions.begin(); iter != Sessions.end(); iter++) {
596                  if (FD_ISSET((*iter).hSession, &selectSet)) {   //Was it this socket?                  if (FD_ISSET((*iter).hSession, &selectSet)) {   //Was it this socket?
597                            currentSocket = (*iter).hSession;  //a hack
598                          if (GetLSCPCommand(iter)) {     //Have we read the entire command?                          if (GetLSCPCommand(iter)) {     //Have we read the entire command?
599                                  dmsg(3,("LSCPServer: Got command on socket %d, calling parser.\n", currentSocket));                                  dmsg(3,("LSCPServer: Got command on socket %d, calling parser.\n", currentSocket));
600                                  int dummy; // just a temporary hack to fulfill the restart() function prototype                                  int dummy; // just a temporary hack to fulfill the restart() function prototype
601                                  restart(NULL, dummy); // restart the 'scanner'                                  restart(NULL, dummy); // restart the 'scanner'
                                 currentSocket = (*iter).hSession;  //a hack  
602                                  itCurrentSession = iter; // another hack                                  itCurrentSession = iter; // another hack
603                                  dmsg(2,("LSCPServer: [%s]\n",bufferedCommands[currentSocket].c_str()));                                  dmsg(2,("LSCPServer: [%s]\n",bufferedCommands[currentSocket].c_str()));
604                                  if ((*iter).bVerbose) { // if echo mode enabled                                  if ((*iter).bVerbose) { // if echo mode enabled
# Line 610  int LSCPServer::Main() { Line 612  int LSCPServer::Main() {
612                                          CloseConnection(iter);                                          CloseConnection(iter);
613                                  }                                  }
614                          }                          }
615                            currentSocket = -1;     //continuation of a hack
616                          //socket may have been closed, iter may be invalid, get out of the loop for now.                          //socket may have been closed, iter may be invalid, get out of the loop for now.
617                          //we'll be back if there is data.                          //we'll be back if there is data.
618                          break;                          break;
# Line 739  bool LSCPServer::GetLSCPCommand( std::ve Line 742  bool LSCPServer::GetLSCPCommand( std::ve
742                                  bufferedCommands[socket] += "\r\n";                                  bufferedCommands[socket] += "\r\n";
743                                  return true; //Complete command was read                                  return true; //Complete command was read
744                          }                          }
745                          bufferedCommands[socket] += c;                          // backspace character - should only happen with shell
746                            if (c == '\b') {
747                                    if (!bufferedCommands[socket].empty()) {
748                                            bufferedCommands[socket] = bufferedCommands[socket].substr(
749                                                    0, bufferedCommands[socket].length() - 1
750                                            );
751                                    }
752                            } else bufferedCommands[socket] += c;
753                            // only if the other side is the LSCP shell application:
754                            // check the current (incomplete) command line for syntax errors,
755                            // possible completions and report everything back to the shell
756                            if ((*iter).bShellInteract) {
757                                    String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter));
758                                    if (!s.empty()) AnswerClient(s + "\n");
759                            }
760                  }                  }
761                  #if defined(WIN32)                  #if defined(WIN32)
762                  if (result == SOCKET_ERROR) {                  if (result == SOCKET_ERROR) {
# Line 801  bool LSCPServer::GetLSCPCommand( std::ve Line 818  bool LSCPServer::GetLSCPCommand( std::ve
818   * @param ReturnMessage - message that will be send to the client   * @param ReturnMessage - message that will be send to the client
819   */   */
820  void LSCPServer::AnswerClient(String ReturnMessage) {  void LSCPServer::AnswerClient(String ReturnMessage) {
821      dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));      dmsg(2,("LSCPServer::AnswerClient(ReturnMessage='%s')", ReturnMessage.c_str()));
822      if (currentSocket != -1) {      if (currentSocket != -1) {
823              LockGuard lock(NotifyMutex);              LockGuard lock(NotifyMutex);
824    
825            // just if other side is LSCP shell: in case respose is a multi-line
826            // one, then inform client about it before sending the actual mult-line
827            // response
828            if (GetCurrentYaccSession()->bShellInteract) {
829                // check if this is a multi-line response
830                int n = 0;
831                for (int i = 0; i < ReturnMessage.size(); ++i)
832                    if (ReturnMessage[i] == '\n') ++n;
833                if (n >= 2) {
834                    dmsg(2,("LSCP Shell <- expect mult-line response\n"));
835                    String s = LSCP_SHK_EXPECT_MULTI_LINE "\r\n";
836    #ifdef MSG_NOSIGNAL
837                    send(currentSocket, s.c_str(), s.size(), MSG_NOSIGNAL);
838    #else
839                    send(currentSocket, s.c_str(), s.size(), 0);
840    #endif                
841                }
842            }
843    
844  #ifdef MSG_NOSIGNAL  #ifdef MSG_NOSIGNAL
845              send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), MSG_NOSIGNAL);              send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), MSG_NOSIGNAL);
846  #else  #else
# Line 1778  String LSCPServer::SetAudioOutputType(St Line 1815  String LSCPServer::SetAudioOutputType(St
1815      return result.Produce();      return result.Produce();
1816  }  }
1817    
1818    String LSCPServer::AddChannelMidiInput(uint uiSamplerChannel, uint MIDIDeviceId, uint MIDIPort) {
1819        dmsg(2,("LSCPServer: AddChannelMidiInput(uiSamplerChannel=%d, MIDIDeviceId=%d, MIDIPort=%d)\n",uiSamplerChannel,MIDIDeviceId,MIDIPort));
1820        LSCPResultSet result;
1821        try {
1822            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1823            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1824    
1825            std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1826            if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1827            MidiInputDevice* pDevice = devices[MIDIDeviceId];
1828    
1829            MidiInputPort* pPort = pDevice->GetPort(MIDIPort);
1830            if (!pPort) throw Exception("There is no MIDI input port with index " + ToString(MIDIPort) + " on MIDI input device with index " + ToString(MIDIDeviceId));
1831    
1832            pSamplerChannel->Connect(pPort);
1833        } catch (Exception e) {
1834            result.Error(e);
1835        }
1836        return result.Produce();
1837    }
1838    
1839    String LSCPServer::RemoveChannelMidiInput(uint uiSamplerChannel) {
1840        dmsg(2,("LSCPServer: RemoveChannelMidiInput(uiSamplerChannel=%d)\n",uiSamplerChannel));
1841        LSCPResultSet result;
1842        try {
1843            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1844            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1845            pSamplerChannel->DisconnectAllMidiInputPorts();
1846        } catch (Exception e) {
1847            result.Error(e);
1848        }
1849        return result.Produce();
1850    }
1851    
1852    String LSCPServer::RemoveChannelMidiInput(uint uiSamplerChannel, uint MIDIDeviceId) {
1853        dmsg(2,("LSCPServer: RemoveChannelMidiInput(uiSamplerChannel=%d, MIDIDeviceId=%d)\n",uiSamplerChannel,MIDIDeviceId));
1854        LSCPResultSet result;
1855        try {
1856            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1857            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1858    
1859            std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1860            if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1861            MidiInputDevice* pDevice = devices[MIDIDeviceId];
1862            
1863            std::vector<MidiInputPort*> vPorts = pSamplerChannel->GetMidiInputPorts();
1864            for (int i = 0; i < vPorts.size(); ++i)
1865                if (vPorts[i]->GetDevice() == pDevice)
1866                    pSamplerChannel->Disconnect(vPorts[i]);
1867    
1868        } catch (Exception e) {
1869            result.Error(e);
1870        }
1871        return result.Produce();
1872    }
1873    
1874    String LSCPServer::RemoveChannelMidiInput(uint uiSamplerChannel, uint MIDIDeviceId, uint MIDIPort) {
1875        dmsg(2,("LSCPServer: RemoveChannelMidiInput(uiSamplerChannel=%d, MIDIDeviceId=%d, MIDIPort=%d)\n",uiSamplerChannel,MIDIDeviceId,MIDIPort));
1876        LSCPResultSet result;
1877        try {
1878            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1879            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1880    
1881            std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1882            if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1883            MidiInputDevice* pDevice = devices[MIDIDeviceId];
1884    
1885            MidiInputPort* pPort = pDevice->GetPort(MIDIPort);
1886            if (!pPort) throw Exception("There is no MIDI input port with index " + ToString(MIDIPort) + " on MIDI input device with index " + ToString(MIDIDeviceId));
1887    
1888            pSamplerChannel->Disconnect(pPort);
1889        } catch (Exception e) {
1890            result.Error(e);
1891        }
1892        return result.Produce();
1893    }
1894    
1895    String LSCPServer::ListChannelMidiInputs(uint uiSamplerChannel) {
1896        dmsg(2,("LSCPServer: ListChannelMidiInputs(uiSamplerChannel=%d)\n",uiSamplerChannel));
1897        LSCPResultSet result;
1898        try {
1899            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1900            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1901            std::vector<MidiInputPort*> vPorts = pSamplerChannel->GetMidiInputPorts();
1902    
1903            String s;
1904            for (int i = 0; i < vPorts.size(); ++i) {
1905                const int iDeviceID = vPorts[i]->GetDevice()->MidiInputDeviceID();
1906                const int iPortNr   = vPorts[i]->GetPortNumber();
1907                if (s.size()) s += ",";
1908                s += "{" + ToString(iDeviceID) + ","
1909                         + ToString(iPortNr) + "}";
1910            }
1911            result.Add(s);
1912        } catch (Exception e) {
1913            result.Error(e);
1914        }
1915        return result.Produce();
1916    }
1917    
1918  String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {  String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {
1919      dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));      dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));
1920      LSCPResultSet result;      LSCPResultSet result;
# Line 3859  String LSCPServer::SetEcho(yyparse_param Line 3996  String LSCPServer::SetEcho(yyparse_param
3996      }      }
3997      return result.Produce();      return result.Produce();
3998  }  }
3999    
4000    String LSCPServer::SetShellInteract(yyparse_param_t* pSession, double boolean_value) {
4001        dmsg(2,("LSCPServer: SetShellInteract(val=%f)\n", boolean_value));
4002        LSCPResultSet result;
4003        try {
4004            if      (boolean_value == 0) pSession->bShellInteract = false;
4005            else if (boolean_value == 1) pSession->bShellInteract = true;
4006            else throw Exception("Not a boolean value, must either be 0 or 1");
4007        } catch (Exception e) {
4008            result.Error(e);
4009        }
4010        return result.Produce();
4011    }
4012    
4013  }  }

Legend:
Removed from v.2427  
changed lines
  Added in v.2515

  ViewVC Help
Powered by ViewVC