--- liblscp/trunk/examples/example_server.c 2004/07/08 09:13:36 188 +++ liblscp/trunk/examples/example_server.c 2007/01/15 11:08:28 1031 @@ -1,7 +1,8 @@ // example_server.c // /**************************************************************************** - Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved. + liblscp - LinuxSampler Control Protocol API + Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -13,9 +14,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *****************************************************************************/ @@ -30,487 +31,871 @@ static WSADATA _wsaData; #endif + //////////////////////////////////////////////////////////////////////// lscp_status_t server_callback ( lscp_connect_t *pConnect, const char *pchBuffer, int cchBuffer, void *pvData ) { - lscp_status_t ret = LSCP_OK; - lscp_parser_t tok; - const char *pszResult = NULL; - char szTemp[256]; - int i; - static int iSamplerChannel = 0; - static int iAudioDevice = 0; - static int iMidiDevice = 0; - - if (pchBuffer == NULL) { - fprintf(stderr, "server_callback: addr=%s port=%d: ", - inet_ntoa(pConnect->client.addr.sin_addr), - htons(pConnect->client.addr.sin_port)); - switch (cchBuffer) { - case LSCP_CONNECT_OPEN: - fprintf(stderr, "New client connection.\n"); - break; - case LSCP_CONNECT_CLOSE: - fprintf(stderr, "Connection closed.\n"); - break; - } - return ret; - } - - lscp_socket_trace("server_callback", &(pConnect->client.addr), pchBuffer, cchBuffer); - - lscp_parser_init(&tok, pchBuffer, cchBuffer); - - if (lscp_parser_test(&tok, "GET")) { - if (lscp_parser_test(&tok, "CHANNEL")) { - if (lscp_parser_test(&tok, "INFO")) { - // Getting sampler channel informations: - // GET CHANNEL INFO - pszResult = "ENGINE_NAME: DummyEngine\r\n" - "INSTRUMENT_FILE: DummyInstrument.gig\r\n" - "INSTRUMENT_NR: 0\r\n" - "INSTRUMENT_STATUS: 100\r\n" - "AUDIO_OUTPUT_DEVICE: 0\r\n" - "AUDIO_OUTPUT_CHANNELS: 2\r\n" - "AUDIO_OUTPUT_ROUTING: 0,1\r\n" - "MIDI_INPUT_DEVICE: 0\r\n" - "MIDI_INPUT_PORT: 0\r\n" - "MIDI_INPUT_CHANNEL: ALL\r\n" - "VOLUME: 0.5\r\n"; - } - else if (lscp_parser_test(&tok, "VOICE_COUNT")) { - // Current number of active voices: - // GET CHANNEL VOICE_COUNT - sprintf(szTemp, "%d", rand() % 100); - pszResult = szTemp; - } - else if (lscp_parser_test(&tok, "STREAM_COUNT")) { - // Current number of active disk streams: - // GET CHANNEL STREAM_COUNT - pszResult = "3\r\n"; - } - else if (lscp_parser_test(&tok, "BUFFER_FILL")) { - if (lscp_parser_test(&tok, "BYTES")) { - // Current fill state of disk stream buffers: - // GET CHANNEL BUFFER_FILL BYTES - sprintf(szTemp, "[1]%d,[2]%d,[3]%d\r\n", rand(), rand(), rand()); - pszResult = szTemp; - } - else if (lscp_parser_test(&tok, "PERCENTAGE")) { - // Current fill state of disk stream buffers: - // GET CHANNEL BUFFER_FILL PERCENTAGE - sprintf(szTemp, "[1]%d%%,[2]%d%%,[3]%d%%\r\n", rand() % 100, rand() % 100, rand() % 100); - pszResult = szTemp; - } - else ret = LSCP_FAILED; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "CHANNELS")) { - // Current number of sampler channels: - // GET CHANNELS - sprintf(szTemp, "%d", iSamplerChannel); - pszResult = szTemp; - } - else if (lscp_parser_test(&tok, "AVAILABLE_AUDIO_OUTPUT_DRIVERS")) { - // Getting all available audio output drivers. - // GET AVAILABLE_AUDIO_OUTPUT_DRIVERS - pszResult = "Alsa,Jack,CoreAudio\r\n"; - } - else if (lscp_parser_test(&tok, "AVAILABLE_MIDI_INPUT_DRIVERS")) { - // Getting all available MIDI input drivers. - // GET AVAILABLE_MIDI_INPUT_DRIVERS - pszResult = "Alsa,MidiShare,CoreMidi\r\n"; - } - else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER", "INFO")) { - // Getting informations about a specific audio output driver. - // GET AUDIO_OUTPUT_DRIVER INFO - if (lscp_parser_test(&tok, "Alsa")) { - pszResult = "DESCRIPTION: 'ALSA PCM'\r\n" - "VERSION: '1.0'\r\n" - "PARAMETERS: channels,samplerate,active,card\r\n"; - } - else if (lscp_parser_test(&tok, "Jack")) { - pszResult = "DESCRIPTION: JACK Audio Connection Kit\r\n" - "VERSION: 0.98.1\r\n" - "PARAMETERS: channels,samplerate,active\r\n"; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER", "INFO")) { - // Getting informations about a specific MIDI input driver. - // GET MIDI_INPUT_DRIVER INFO - if (lscp_parser_test(&tok, "Alsa")) { - pszResult = "DESCRIPTION: ALSA Sequencer\r\n" - "VERSION: 1.0\r\n" - "PARAMETERS: ports,active\r\n"; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER_PARAMETER", "INFO")) { - // Getting informations about a specific audio output driver parameter. - // GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO - if (lscp_parser_test2(&tok, "Alsa", "active")) { - pszResult = "DESCRIPTION: 'ALSA PCM device active state'\r\n" - "TYPE: BOOL\r\n" - "MANDATORY: TRUE\r\n" - "FIX: TRUE\r\n" - "MULTIPLICITY: FALSE\r\n" - "DEPENDS: channels,samplerate,card\r\n" - "DEFAULT: TRUE\r\n" - "RANGE_MIN: FALSE\r\n" - "RANGE_MAX: TRUE\r\n" - "POSSIBILITIES: FALSE,TRUE\r\n"; - } - else if (lscp_parser_test2(&tok, "Jack", "active")) { - pszResult = "DESCRIPTION: 'JACK device active state'\r\n" - "TYPE: BOOL\r\n" - "MANDATORY: TRUE\r\n" - "FIX: TRUE\r\n" - "MULTIPLICITY: FALSE\r\n" - "DEPENDS: channels,samplerate\r\n" - "DEFAULT: TRUE\r\n" - "RANGE_MIN: FALSE\r\n" - "RANGE_MAX: TRUE\r\n" - "POSSIBILITIES: FALSE,TRUE\r\n"; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER_PARAMETER", "INFO")) { - // Getting informations about a specific MIDI input driver parameter. - // GET MIDI_INPUT_DRIVER_PARAMETER INFO - if (lscp_parser_test2(&tok, "Alsa", "active")) { - pszResult = "DESCRIPTION: 'ALSA Sequencer device active state'\r\n" - "TYPE: BOOL\r\n" - "MANDATORY: TRUE\r\n" - "FIX: TRUE\r\n" - "MULTIPLICITY: FALSE\r\n" - "DEPENDS: channels,ports\r\n" - "DEFAULT: TRUE\r\n" - "RANGE_MIN: FALSE\r\n" - "RANGE_MAX: TRUE\r\n" - "POSSIBILITIES: FALSE,TRUE\r\n"; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DEVICE", "INFO")) { - // Getting informations about a specific audio output device. - // GET AUDIO_OUTPUT_DEVICE INFO - if (lscp_parser_nextint(&tok) < iAudioDevice) { - pszResult = "driver: Alsa\r\n" - "active: TRUE\r\n" - "channels: 2\r\n" - "samplerate: 44100\r\n"; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test2(&tok, "MIDI_INPUT_DEVICE", "INFO")) { - // Getting informations about a specific MIDI input device. - // GET MIDI_INPUT_DEVICE INFO - if (lscp_parser_nextint(&tok) < iMidiDevice) { - pszResult = "driver: Alsa\r\n" - "active: TRUE\r\n" - "channels: 16\r\n" - "ports: 1\r\n"; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICES")) { - // Getting all created audio output device count. - // GET AUDIO_OUTPUT_DEVICES - sprintf(szTemp, "%d\r\n", iAudioDevice); - pszResult = szTemp; - } - else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICES")) { - // Getting all created MID input device count. - // GET MIDI_INPUT_DEVICES - sprintf(szTemp, "%d\r\n", iMidiDevice); - pszResult = szTemp; - } - else if (lscp_parser_test(&tok, "AVAILABLE_ENGINES")) { - // Getting all available engines: - // GET AVAILABLE_ENGINES - pszResult = "GigEngine,DLSEngine,AkaiEngine\r\n"; - } - else if (lscp_parser_test2(&tok, "ENGINE", "INFO")) { - // Getting information about an engine. - // GET ENGINE INFO - if (lscp_parser_test(&tok, "GigEngine")) { - pszResult = "DESCRIPTION: GigaSampler Engine\r\n" - "VERSION: 0.3\r\n"; - } - else if (lscp_parser_test(&tok, "DLSEngine")) { - pszResult = "DESCRIPTION: 'DLS Generic Engine'\r\n" - "VERSION: 0.2\r\n"; - } - else if (lscp_parser_test(&tok, "AkaiEngine")) { - pszResult = "DESCRIPTION: Akai Sampler Engine\r\n" - "VERSION: 0.1\r\n"; - } - else ret = LSCP_FAILED; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "LIST")) { - if (lscp_parser_test(&tok, "CHANNELS")) { - // Getting all created sampler channel list. - // LIST CHANNELS - if (iSamplerChannel > 0) { - strcpy(szTemp, "0"); - for (i = 1; i < iSamplerChannel && strlen(szTemp) < sizeof(szTemp) - 8; i++) - sprintf(szTemp + strlen(szTemp), ",%d", i); - strcat(szTemp, "\r\n"); - pszResult = szTemp; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICES")) { - // Getting all created audio output device list. - // LIST AUDIO_OUTPUT_DEVICES - if (iAudioDevice > 0) { - strcpy(szTemp, "0"); - for (i = 1; i < iAudioDevice && strlen(szTemp) < sizeof(szTemp) - 8; i++) - sprintf(szTemp + strlen(szTemp), ",%d", i); - strcat(szTemp, "\r\n"); - pszResult = szTemp; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICES")) { - // Getting all created MID input device list. - // LIST MIDI_INPUT_DEVICES - if (iMidiDevice > 0) { - strcpy(szTemp, "0"); - for (i = 1; i < iMidiDevice && strlen(szTemp) < sizeof(szTemp) - 8; i++) - sprintf(szTemp + strlen(szTemp), ",%d", i); - strcat(szTemp, "\r\n"); - pszResult = szTemp; - } - else ret = LSCP_FAILED; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "SET")) { - if (lscp_parser_test(&tok, "CHANNEL")) { - if (lscp_parser_test(&tok, "VOLUME")) { - // Setting channel volume: - // SET CHANNEL VOLUME - } - else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_TYPE")) { - // Setting audio output type: - // SET CHANNEL AUDIO_OUTPUT_TYPE - } - else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) { - // Setting audio output device: - // SET CHANNEL AUDIO_OUTPUT_DEVICE - } - else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_CHANNEL")) { - // Setting audio output channel: - // SET CHANNEL AUDIO_OUTPUT_CHANNEL - } - else if (lscp_parser_test(&tok, "MIDI_INPUT_TYPE")) { - // Setting MIDI input type: - // SET CHANNEL MIDI_INPUT_TYPE - } - else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) { - // Setting MIDI input device: - // SET CHANNEL MIDI_INPUT_DEVICE - } - else if (lscp_parser_test(&tok, "MIDI_INPUT_PORT")) { - // Setting MIDI input port: - // SET CHANNEL MIDI_INPUT_PORT - } - else if (lscp_parser_test(&tok, "MIDI_INPUT_CHANNEL")) { - // Setting MIDI input channel: - // SET CHANNEL MIDI_INPUT_CHANNEL - } - else ret = LSCP_FAILED; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "LOAD")) { - if (lscp_parser_test(&tok, "ENGINE")) { - // Loading a sampler engine: - // LOAD ENGINE - } - else if (lscp_parser_test(&tok, "INSTRUMENT")) { - // Loading an instrument: - // LOAD INSTRUMENT [NON_MODAL] - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test2(&tok, "ADD", "CHANNEL")) { - // Adding a new sampler channel: - // ADD CHANNEL - if (iSamplerChannel < 16) { - sprintf(szTemp, "OK[%d]", iSamplerChannel++); - pszResult = szTemp; - } else { - iSamplerChannel = 0; - ret = LSCP_FAILED; - } - } - else if (lscp_parser_test2(&tok, "REMOVE", "CHANNEL")) { - // Removing a sampler channel: - // REMOVE CHANNEL - if (lscp_parser_nextint(&tok) < iSamplerChannel) - iSamplerChannel--; - else - ret = LSCP_FAILED; - } - else if (lscp_parser_test2(&tok, "RESET", "CHANNEL")) { - // Resetting a sampler channel: - // RESET CHANNEL - if (lscp_parser_nextint(&tok) > iSamplerChannel) - ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "CREATE")) { - if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) { - // Creating an audio output device. - // CREATE AUDIO_OUTPUT_DEVICE [] - if (iAudioDevice < 8) { - sprintf(szTemp, "OK[%d]", iAudioDevice++); - pszResult = szTemp; - } else { - iAudioDevice = 0; - ret = LSCP_FAILED; - } - } - else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) { - // Creating an MIDI input device. - // CREATE MIDI_INPUT_DEVICE [] - if (iMidiDevice < 8) { - sprintf(szTemp, "OK[%d]", iMidiDevice++); - pszResult = szTemp; - } else { - iMidiDevice = 0; - ret = LSCP_FAILED; - } - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "DESTROY")) { - if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) { - // Destroying an audio output device. - // DESTROY AUDIO_OUTPUT_DEVICE - if (lscp_parser_nextint(&tok) < iAudioDevice) - iAudioDevice--; - else - ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) { - // Destroying an MIDI intput device. - // DESTROY MIDI_INPUT_DEVICE - if (lscp_parser_nextint(&tok) < iMidiDevice) - iMidiDevice--; - else - ret = LSCP_FAILED; - } - else ret = LSCP_FAILED; - } - else if (lscp_parser_test(&tok, "SUBSCRIBE")) { - // Register frontend for receiving event notification messages: - // SUBSCRIBE - ret = lscp_server_subscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok))); - } - else if (lscp_parser_test(&tok, "UNSUBSCRIBE")) { - // Deregister frontend for not receiving event notification messages anymore: - // UNSUBSCRIBE - ret = lscp_server_unsubscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok))); - } - else if (lscp_parser_test(&tok, "QUIT")) { - // Close client connection: - // QUIT - lscp_parser_free(&tok); - return LSCP_FAILED; // Disconnect. - } - else ret = LSCP_FAILED; + lscp_status_t ret = LSCP_OK; + lscp_parser_t tok; + const char *pszResult = NULL; + char szTemp[4096]; + int i; + static int iSamplerChannel = 0; + static int iAudioDevice = 0; + static int iMidiDevice = 0; + static int iFxSend = 0; + static int iMidiMaps = 0; + static int iMidiInstruments = 0; + static float fVolume = 1.0f; + + if (pchBuffer == NULL) { + fprintf(stderr, "server_callback: addr=%s port=%d: ", + inet_ntoa(pConnect->client.addr.sin_addr), + htons(pConnect->client.addr.sin_port)); + switch (cchBuffer) { + case LSCP_CONNECT_OPEN: + fprintf(stderr, "New client connection.\n"); + break; + case LSCP_CONNECT_CLOSE: + fprintf(stderr, "Connection closed.\n"); + break; + } + return ret; + } + + lscp_socket_trace("server_callback", &(pConnect->client.addr), pchBuffer, cchBuffer); + + lscp_parser_init(&tok, pchBuffer, cchBuffer); + + if (lscp_parser_test(&tok, "GET")) { + if (lscp_parser_test(&tok, "CHANNEL")) { + if (lscp_parser_test(&tok, "INFO")) { + // Getting sampler channel informations: + // GET CHANNEL INFO + pszResult = "ENGINE_NAME: DummyEngine\r\n" + "INSTRUMENT_FILE: DummyInstrument.gig\r\n" + "INSTRUMENT_NR: 0\r\n" + "INSTRUMENT_NAME: Dummy Instrument\r\n" + "INSTRUMENT_STATUS: 100\r\n" + "AUDIO_OUTPUT_DEVICE: 0\r\n" + "AUDIO_OUTPUT_CHANNELS: 2\r\n" + "AUDIO_OUTPUT_ROUTING: 0,1\r\n" + "MIDI_INPUT_DEVICE: 0\r\n" + "MIDI_INPUT_PORT: 0\r\n" + "MIDI_INPUT_CHANNEL: ALL\r\n" + "VOLUME: 0.5\r\n" + "MUTE: FALSE\r\n" + "SOLO: TRUE\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "VOICE_COUNT")) { + // Current number of active voices: + // GET CHANNEL VOICE_COUNT + sprintf(szTemp, "%d\r\n", rand() % 100); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "STREAM_COUNT")) { + // Current number of active disk streams: + // GET CHANNEL STREAM_COUNT + pszResult = "3\r\n"; + } + else if (lscp_parser_test(&tok, "BUFFER_FILL")) { + if (lscp_parser_test(&tok, "BYTES")) { + // Current fill state of disk stream buffers: + // GET CHANNEL BUFFER_FILL BYTES + sprintf(szTemp, "[1]%d,[2]%d,[3]%d\r\n", rand(), rand(), rand()); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "PERCENTAGE")) { + // Current fill state of disk stream buffers: + // GET CHANNEL BUFFER_FILL PERCENTAGE + sprintf(szTemp, "[1]%d%%,[2]%d%%,[3]%d%%\r\n", rand() % 100, rand() % 100, rand() % 100); + pszResult = szTemp; + } + else ret = LSCP_FAILED; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "CHANNELS")) { + // Current number of sampler channels: + // GET CHANNELS + sprintf(szTemp, "%d\r\n", iSamplerChannel); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "AVAILABLE_AUDIO_OUTPUT_DRIVERS")) { + // Getting all available audio output driver count. + // GET AVAILABLE_AUDIO_OUTPUT_DRIVERS + pszResult = "2\r\n"; + } + else if (lscp_parser_test(&tok, "AVAILABLE_MIDI_INPUT_DRIVERS")) { + // Getting all available MIDI input driver count. + // GET AVAILABLE_MIDI_INPUT_DRIVERS + pszResult = "1\r\n"; + } + else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER", "INFO")) { + // Getting informations about a specific audio output driver. + // GET AUDIO_OUTPUT_DRIVER INFO + if (lscp_parser_test(&tok, "Alsa")) { + pszResult = "DESCRIPTION: 'ALSA PCM'\r\n" + "VERSION: '1.0'\r\n" + "PARAMETERS: channels,samplerate,active\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "Jack")) { + pszResult = "DESCRIPTION: JACK Audio Connection Kit\r\n" + "VERSION: 0.98.1\r\n" + "PARAMETERS: channels,samplerate,active\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER", "INFO")) { + // Getting informations about a specific MIDI input driver. + // GET MIDI_INPUT_DRIVER INFO + if (lscp_parser_test(&tok, "Alsa")) { + pszResult = "DESCRIPTION: ALSA Sequencer\r\n" + "VERSION: 1.0\r\n" + "PARAMETERS: ports,active\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER_PARAMETER", "INFO")) { + // Getting informations about a specific audio output driver parameter. + // GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO + if (lscp_parser_test(&tok, "Alsa")) { + if (lscp_parser_test(&tok, "active")) { + pszResult = "DESCRIPTION: 'ALSA PCM active state'\r\n" + "TYPE: BOOL\r\n" + "MANDATORY: TRUE\r\n" + "FIX: TRUE\r\n" + "MULTIPLICITY: FALSE\r\n" + "DEPENDS: channels,samplerate,card\r\n" + "DEFAULT: TRUE\r\n" + "RANGE_MIN: FALSE\r\n" + "RANGE_MAX: TRUE\r\n" + "POSSIBILITIES: FALSE,TRUE\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "channels")) { + pszResult = "DESCRIPTION: 'Number of ALSA PCM channels'\r\n" + "TYPE: INT\r\n" + "MANDATORY: TRUE\r\n" + "FIX: TRUE\r\n" + "MULTIPLICITY: FALSE\r\n" + "DEFAULT: 2\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "samplerate")) { + pszResult = "DESCRIPTION: 'ALSA PCM sample rate'\r\n" + "TYPE: INT\r\n" + "MANDATORY: TRUE\r\n" + "FIX: TRUE\r\n" + "MULTIPLICITY: TRUE\r\n" + "DEFAULT: 44100\r\n" + "POSSIBILITIES: 44100,48000,96000\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "Jack")) { + if (lscp_parser_test(&tok, "active")) { + pszResult = "DESCRIPTION: 'JACK active state'\r\n" + "TYPE: BOOL\r\n" + "MANDATORY: TRUE\r\n" + "FIX: TRUE\r\n" + "MULTIPLICITY: FALSE\r\n" + "DEPENDS: channels,samplerate\r\n" + "DEFAULT: TRUE\r\n" + "RANGE_MIN: FALSE\r\n" + "RANGE_MAX: TRUE\r\n" + "POSSIBILITIES: FALSE,TRUE\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "channels")) { + pszResult = "DESCRIPTION: 'Number of JACK audio channels'\r\n" + "TYPE: INT\r\n" + "MANDATORY: TRUE\r\n" + "FIX: TRUE\r\n" + "MULTIPLICITY: FALSE\r\n" + "DEFAULT: 2\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "samplerate")) { + pszResult = "DESCRIPTION: 'JACK sample rate'\r\n" + "TYPE: INT\r\n" + "MANDATORY: TRUE\r\n" + "FIX: TRUE\r\n" + "MULTIPLICITY: TRUE\r\n" + "DEFAULT: 44100\r\n" + "POSSIBILITIES: 44100,48000,96000\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER_PARAMETER", "INFO")) { + // Getting informations about a specific MIDI input driver parameter. + // GET MIDI_INPUT_DRIVER_PARAMETER INFO + if (lscp_parser_test(&tok, "Alsa")) { + if (lscp_parser_test(&tok, "active")) { + pszResult = "DESCRIPTION: 'ALSA Sequencer device active state'\r\n" + "TYPE: BOOL\r\n" + "MANDATORY: TRUE\r\n" + "FIX: TRUE\r\n" + "MULTIPLICITY: FALSE\r\n" + "DEPENDS: channels,ports\r\n" + "DEFAULT: TRUE\r\n" + "RANGE_MIN: FALSE\r\n" + "RANGE_MAX: TRUE\r\n" + "POSSIBILITIES: FALSE,TRUE\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "ports")) { + pszResult = "DESCRIPTION: 'Number of ALSA Sequencer ports'\r\n" + "TYPE: INT\r\n" + "MANDATORY: FALSE\r\n" + "FIX: FALSE\r\n" + "MULTIPLICITY: FALSE\r\n" + "DEFAULT: 1\r\n" + "RANGE_MIN: 1\r\n" + "RANGE_MAX: 4\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DEVICE", "INFO")) { + // Getting informations about a specific audio output device. + // GET AUDIO_OUTPUT_DEVICE INFO + if (lscp_parser_nextint(&tok) < iAudioDevice) { + pszResult = "driver: Alsa\r\n" + "active: TRUE\r\n" + "channels: 2\r\n" + "samplerate: 44100\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "MIDI_INPUT_DEVICE", "INFO")) { + // Getting informations about a specific MIDI input device. + // GET MIDI_INPUT_DEVICE INFO + if (lscp_parser_nextint(&tok) < iMidiDevice) { + pszResult = "driver: Alsa\r\n" + "active: TRUE\r\n" + "channels: 16\r\n" + "ports: 1\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_CHANNEL", "INFO")) { + // Getting informations about an audio channel. + // GET AUDIO_OUTPUT_CHANNEL INFO + if (lscp_parser_nextint(&tok) < iAudioDevice) { + pszResult = "name: DummyMonitor\r\n" + "is_mix_channel: FALSE\r\n" + "mix_channel_destination: 0\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "MIDI_INPUT_PORT", "INFO")) { + // Getting informations about a MIDI port. + // GET MIDI_INPUT_PORT INFO + if (lscp_parser_nextint(&tok) < iMidiDevice) { + pszResult = "name: DummyKeyboard\r\n" + "alsa_seq_bindings: '64:0'\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_CHANNEL_PARAMETER", "INFO")) { + // Getting informations about specific audio channel parameter. + // GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO + if (lscp_parser_nextint(&tok) < iAudioDevice) { + lscp_parser_nextint(&tok); + if (lscp_parser_test(&tok, "is_mix_channel")) { + pszResult = "DESCRIPTION: 'Whether this is an audio mix channel'\r\n" + "TYPE: BOOL\r\n" + "MANDATORY: TRUE\r\n" + "FIX: FALSE\r\n" + "MULTIPLICITY: FALSE\r\n" + "POSSIBILITIES: FALSE,TRUE\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "mix_channel_destination")) { + pszResult = "DESCRIPTION: 'Audio mix channel destination'\r\n" + "TYPE: INT\r\n" + "MANDATORY: TRUE\r\n" + "FIX: FALSE\r\n" + "MULTIPLICITY: TRUE\r\n" + "POSSIBILITIES: 0,1\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "MIDI_INPUT_PORT_PARAMETER", "INFO")) { + // Getting informations about specific MIDI port parameter. + // GET MIDI_INPUT_PORT_PARAMETER INFO + if (lscp_parser_nextint(&tok) < iMidiDevice) { + lscp_parser_nextint(&tok); + if (lscp_parser_test(&tok, "alsa_seq_bindings")) { + pszResult = "DESCRIPTION: 'Alsa sequencer port bindings'\r\n" + "TYPE: STRING\r\n" + "MANDATORY: TRUE\r\n" + "FIX: FALSE\r\n" + "MULTIPLICITY: TRUE\r\n" + "POSSIBILITIES: '64:0','68:0','68:1'\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICES")) { + // Getting all created audio output device count. + // GET AUDIO_OUTPUT_DEVICES + sprintf(szTemp, "%d\r\n", iAudioDevice); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICES")) { + // Getting all created MID input device count. + // GET MIDI_INPUT_DEVICES + sprintf(szTemp, "%d\r\n", iMidiDevice); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "AVAILABLE_ENGINES")) { + // Getting all available engine count: + // GET AVAILABLE_ENGINES + pszResult = "3\r\n"; + } + else if (lscp_parser_test2(&tok, "SERVER", "INFO")) { + // Getting information about the server. + // GET SERVER INFO + sprintf(szTemp, "DESCRIPTION: example_server (%s) %s\r\n" + "VERSION: %s\r\n.\r\n", lscp_server_package(), + lscp_server_build(), lscp_server_version()); + pszResult = szTemp; + } + else if (lscp_parser_test2(&tok, "ENGINE", "INFO")) { + // Getting information about an engine. + // GET ENGINE INFO + if (lscp_parser_test(&tok, "GigEngine")) { + pszResult = "DESCRIPTION: GigaSampler Engine\r\n" + "VERSION: 0.3\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "DLSEngine")) { + pszResult = "DESCRIPTION: 'DLS Generic Engine'\r\n" + "VERSION: 0.2\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "AkaiEngine")) { + pszResult = "DESCRIPTION: Akai Sampler Engine\r\n" + "VERSION: 0.1\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "TOTAL_VOICE_COUNT")) { + // Current number of active voices: + // GET TOTAL_VOICE_COUNT + sprintf(szTemp, "%d\r\n", rand() % 100); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "TOTAL_VOICE_COUNT_MAX")) { + // Maximum amount of active voices: + // GET TOTAL_VOICE_COUNT_MAX + sprintf(szTemp, "%d\r\n", rand() % 100); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "VOLUME")) { + // Get global volume attenuation: + // GET VOLUME + sprintf(szTemp, "%g\r\n", fVolume); + pszResult = szTemp; + } + else if (lscp_parser_test2(&tok, "FX_SEND", "INFO")) { + // Getting effect send informations: + // GET FX_SEND INFO + pszResult = "NAME: DummyFxSend\r\n" + "MIDI_CONTROLLER: 99\r\n" + "AUDIO_OUTPUT_ROUTING: 0,1\r\n" + "LEVEL: 0.15\r\n" + ".\r\n"; + } + else if (lscp_parser_test(&tok, "FX_SENDS")) { + // Get ammount of effect sends on a sampler channel: + // GET FX_SENDS + sprintf(szTemp, "%d\r\n", iFxSend); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "MIDI_INSTRUMENTS")) { + // Get the total count of MIDI instrument map entries: + // GET MIDI_INSTRUMENTS + sprintf(szTemp, "%d\r\n", iMidiInstruments); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "MIDI_INSTRUMENT_MAPS")) { + // Get the total count of MIDI instrument maps: + // GET MIDI_INSTRUMENT_MAPS + sprintf(szTemp, "%d\r\n", iMidiMaps); + pszResult = szTemp; + } + else if (lscp_parser_test2(&tok, "MIDI_INSTRUMENT_MAP", "INFO")) { + // Getting information about a MIDI instrument map entry: + // GET MIDI_INSTRUMENT_MAP INFO + strcpy(szTemp, "NAME: "); + switch (lscp_parser_nextint(&tok)) { + case 0: + strcat(szTemp, "Chromatic\r\n"); + break; + case 1: + strcat(szTemp, "Drum Kits\r\n"); + break; + } + strcat(szTemp, ".\r\n"); + pszResult = szTemp; + } + else if (lscp_parser_test2(&tok, "MIDI_INSTRUMENT", "INFO")) { + // Getting information about a MIDI instrument map entry: + // GET MIDI_INSTRUMENT INFO + pszResult = "NAME: DummyName\r\n" + "ENGINE_NAME: DummyEngine\r\n" + "INSTRUMENT_FILE: DummyInstrument.gig\r\n" + "INSTRUMENT_NR: 0\r\n" + "INSTRUMENT_NAME: Dummy Instrument\r\n" + "LOAD_MODE: ON_DEMAND\r\n" + "VOLUME: 0.5\r\n" + ".\r\n"; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "LIST")) { + if (lscp_parser_test(&tok, "CHANNELS")) { + // Getting all created sampler channel list. + // LIST CHANNELS + szTemp[0] = (char) 0; + for (i = 0; i < iSamplerChannel && strlen(szTemp) < sizeof(szTemp) - 8; i++) { + if (i > 0) + strcat(szTemp, ","); + sprintf(szTemp + strlen(szTemp), "%d", i); + } + strcat(szTemp, "\r\n"); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "AVAILABLE_ENGINES")) { + // Getting all available engines: + // LIST AVAILABLE_ENGINES + pszResult = "GigEngine,DLSEngine,AkaiEngine\r\n"; + } + else if (lscp_parser_test(&tok, "AVAILABLE_AUDIO_OUTPUT_DRIVERS")) { + // Getting all available audio output drivers. + // LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS + pszResult = "ALSA,JACK\r\n"; + } + else if (lscp_parser_test(&tok, "AVAILABLE_MIDI_INPUT_DRIVERS")) { + // Getting all available MIDI input drivers. + // LIST AVAILABLE_MIDI_INPUT_DRIVERS + pszResult = "ALSA\r\n"; + } + else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICES")) { + // Getting all created audio output device list. + // LIST AUDIO_OUTPUT_DEVICES + szTemp[0] = (char) 0; + for (i = 0; i < iAudioDevice && strlen(szTemp) < sizeof(szTemp) - 8; i++) { + if (i > 0) + strcat(szTemp, ","); + sprintf(szTemp + strlen(szTemp), "%d", i); + } + strcat(szTemp, "\r\n"); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICES")) { + // Getting all created MID input device list. + // LIST MIDI_INPUT_DEVICES + szTemp[0] = (char) 0; + for (i = 0; i < iMidiDevice && strlen(szTemp) < sizeof(szTemp) - 8; i++) { + if (i > 0) + strcat(szTemp, ","); + sprintf(szTemp + strlen(szTemp), "%d", i); + } + strcat(szTemp, "\r\n"); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "FX_SENDS")) { + // Listing all effect sends on a sampler channel: + // LIST FX_SENDS + szTemp[0] = (char) 0; + for (i = 0; i < iFxSend && strlen(szTemp) < sizeof(szTemp) - 8; i++) { + if (i > 0) + strcat(szTemp, ","); + sprintf(szTemp + strlen(szTemp), "%d", i); + } + strcat(szTemp, "\r\n"); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "MIDI_INSTRUMENTS")) { + // Getting indeces of all MIDI instrument map entries: + // LIST MIDI_INSTRUMENTS + szTemp[0] = (char) 0; + for (i = 0; i < iMidiInstruments && strlen(szTemp) < sizeof(szTemp) - 16; i++) { + if (i > 0) + strcat(szTemp, ","); + sprintf(szTemp + strlen(szTemp), "{0,%d,%d}", i / 128, i % 128); + } + strcat(szTemp, "\r\n"); + pszResult = szTemp; + } + else if (lscp_parser_test(&tok, "MIDI_INSTRUMENT_MAPS")) { + // Getting indeces of all MIDI instrument map entries: + // LIST MIDI_INSTRUMENT_MAPS + szTemp[0] = (char) 0; + for (i = 0; i < iMidiMaps && strlen(szTemp) < sizeof(szTemp) - 8; i++) { + if (i > 0) + strcat(szTemp, ","); + sprintf(szTemp + strlen(szTemp), "%d", i); + } + strcat(szTemp, "\r\n"); + pszResult = szTemp; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "SET")) { + if (lscp_parser_test(&tok, "CHANNEL")) { + if (lscp_parser_test(&tok, "VOLUME")) { + // Setting channel volume: + // SET CHANNEL VOLUME + } + else if (lscp_parser_test(&tok, "MUTE")) { + // Muting a sampler channel: + // SET CHANNEL MUTE + } + else if (lscp_parser_test(&tok, "SOLO")) { + // Soloing a sampler channel: + // SET CHANNEL SOLO + } + else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_TYPE")) { + // Setting audio output type: + // SET CHANNEL AUDIO_OUTPUT_TYPE + } + else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) { + // Setting audio output device: + // SET CHANNEL AUDIO_OUTPUT_DEVICE + } + else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_CHANNEL")) { + // Setting audio output channel: + // SET CHANNEL AUDIO_OUTPUT_CHANNEL + } + else if (lscp_parser_test(&tok, "MIDI_INPUT_TYPE")) { + // Setting MIDI input type: + // SET CHANNEL MIDI_INPUT_TYPE + } + else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) { + // Setting MIDI input device: + // SET CHANNEL MIDI_INPUT_DEVICE + } + else if (lscp_parser_test(&tok, "MIDI_INPUT_PORT")) { + // Setting MIDI input port: + // SET CHANNEL MIDI_INPUT_PORT + } + else if (lscp_parser_test(&tok, "MIDI_INPUT_CHANNEL")) { + // Setting MIDI input channel: + // SET CHANNEL MIDI_INPUT_CHANNEL + } + else if (lscp_parser_test(&tok, "MIDI_INSTRUMENT_MAP")) { + // Setting MIDI instrument mapl: + // SET CHANNEL MIDI_INSTRUMENT_MAP + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "VOLUME")) { + // Setting global volume attenuation: + // SET VOLUME + fVolume = lscp_parser_nextnum(&tok); + } + else if (lscp_parser_test(&tok, "FX_SEND")) { + if (lscp_parser_test(&tok, "MIDI_CONTROLLER")) { + // Altering effect send MIDI controller: + // SET FX_SEND MIDI_CONTROLLER + } + else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_CHANNEL")) { + // Altering effect send audio routing: + // SET FX_SEND AUDIO_OUTPUT_CHANNEL + } + else if (lscp_parser_test(&tok, "LEVEL")) { + // Altering effect send audio level: + // SET FX_SEND LEVEL + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "MIDI_INSTRUMENT_MAP", "NAME")) { + // Setting MIDI instrument map name: + // SET MIDI_INSTRUMENT_MAP NAME + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "LOAD")) { + if (lscp_parser_test(&tok, "ENGINE")) { + // Loading a sampler engine: + // LOAD ENGINE + } + else if (lscp_parser_test(&tok, "INSTRUMENT")) { + // Loading an instrument: + // LOAD INSTRUMENT [NON_MODAL] + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "ADD")) { + if (lscp_parser_test(&tok, "CHANNEL")) { + // Adding a new sampler channel: + // ADD CHANNEL + if (iSamplerChannel < 16) { + sprintf(szTemp, "OK[%d]\r\n", iSamplerChannel++); + pszResult = szTemp; + } else { + iSamplerChannel = 0; + ret = LSCP_FAILED; + } + } + else if (lscp_parser_test(&tok, "MIDI_INSTRUMENT_MAP")) { + // Adding a new MIDI instrument map: + // ADD MIDI_INSTRUMENT_MAP + if (iMidiMaps < 2) { + sprintf(szTemp, "OK[%d]\r\n", iMidiMaps++); + pszResult = szTemp; + } else { + iMidiMaps = 0; + ret = LSCP_FAILED; + } + } + } + else if (lscp_parser_test(&tok, "REMOVE")) { + if (lscp_parser_test(&tok, "CHANNEL")) { + // Removing a sampler channel: + // REMOVE CHANNEL + if (lscp_parser_nextint(&tok) >= 0) + iSamplerChannel--; + else + ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "MIDI_INSTRUMENT_MAP")) { + // Removing a MIDI instrument map: + // REMOVE MIDI_INSTRUMENT_MAP + if (lscp_parser_nextint(&tok) >= 0) + iMidiMaps--; + else + ret = LSCP_FAILED; + } + } + else if (lscp_parser_test(&tok, "RESET")) { + if (lscp_parser_test(&tok, "CHANNEL")) { + // Resetting a sampler channel: + // RESET CHANNEL + if (lscp_parser_nextint(&tok) > iSamplerChannel) + ret = LSCP_FAILED; + } else { + // Reset sampler: + // RESET + iSamplerChannel = 0; + iAudioDevice = 0; + iMidiDevice = 0; + iMidiMaps = 0; + iMidiInstruments = 0; + } + } + else if (lscp_parser_test(&tok, "CREATE")) { + if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) { + // Creating an audio output device. + // CREATE AUDIO_OUTPUT_DEVICE [] + if (iAudioDevice < 8) { + sprintf(szTemp, "OK[%d]\r\n", iAudioDevice++); + pszResult = szTemp; + } else { + iAudioDevice = 0; + ret = LSCP_FAILED; + } + } + else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) { + // Creating an MIDI input device. + // CREATE MIDI_INPUT_DEVICE [] + if (iMidiDevice < 8) { + sprintf(szTemp, "OK[%d]\r\n", iMidiDevice++); + pszResult = szTemp; + } else { + iMidiDevice = 0; + ret = LSCP_FAILED; + } + } + else if (lscp_parser_test(&tok, "FX_SEND")) { + // Adding an effect send to a sampler channel: + // CREATE FX_SEND [] + if (iFxSend < 8) { + sprintf(szTemp, "OK[%d]\r\n", iFxSend++); + pszResult = szTemp; + } else { + iFxSend = 0; + ret = LSCP_FAILED; + } + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "DESTROY")) { + if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) { + // Destroying an audio output device. + // DESTROY AUDIO_OUTPUT_DEVICE + if (lscp_parser_nextint(&tok) >= 0 && iAudioDevice > 0) + iAudioDevice--; + else + ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) { + // Destroying an MIDI intput device. + // DESTROY MIDI_INPUT_DEVICE + if (lscp_parser_nextint(&tok) >= 0 && iMidiDevice > 0) + iMidiDevice--; + else + ret = LSCP_FAILED; + } + else if (lscp_parser_test(&tok, "FX_SEND")) { + // Removing an effect send from a sampler channel: + // CREATE FX_SEND + if (lscp_parser_nextint(&tok) >= 0 && iFxSend > 0) + iFxSend--; + else + ret = LSCP_FAILED; + } + else ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "MAP", "MIDI_INSTRUMENT")) { + // Create or replace a MIDI instrumnet map entry: + // MAP MIDI_INSTRUMENT + // [] + iMidiInstruments++; + } + else if (lscp_parser_test2(&tok, "UNMAP", "MIDI_INSTRUMENT")) { + // Remove an entry from the MIDI instrument map: + // UNMAP MIDI_INSTRUMENT + if (iMidiInstruments > 0) + iMidiInstruments--; + else + ret = LSCP_FAILED; + } + else if (lscp_parser_test2(&tok, "CLEAR", "MIDI_INSTRUMENTS")) { + // Clear the MIDI instrumnet map: + // CLEAR MIDI_INSTRUMENTS + iMidiInstruments = 0; + } + else if (lscp_parser_test(&tok, "SUBSCRIBE")) { + // Register frontend for receiving event notification messages: + // SUBSCRIBE + ret = lscp_server_subscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok))); + } + else if (lscp_parser_test(&tok, "UNSUBSCRIBE")) { + // Deregister frontend for not receiving event notification messages anymore: + // UNSUBSCRIBE + ret = lscp_server_unsubscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok))); + } + else if (lscp_parser_test(&tok, "QUIT")) { + // Close client connection: + // QUIT + lscp_parser_free(&tok); + return LSCP_FAILED; // Disconnect. + } + else ret = LSCP_FAILED; - lscp_parser_free(&tok); + lscp_parser_free(&tok); - if (pszResult == NULL) - pszResult = (ret == LSCP_OK ? "OK\r\n" : "ERR:1:Failed\r\n"); + if (pszResult == NULL) + pszResult = (ret == LSCP_OK ? "OK\r\n" : "ERR:1:Failed\r\n"); - fprintf(stderr, "> %s", pszResult); + fprintf(stderr, "> %s", pszResult); - return lscp_server_result(pConnect, pszResult, strlen(pszResult)); + return lscp_server_result(pConnect, pszResult, strlen(pszResult)); } + //////////////////////////////////////////////////////////////////////// + void server_usage (void) { - printf("\n %s %s (Build: %s)\n", lscp_server_package(), lscp_server_version(), lscp_server_build()); + printf("\n %s %s (Build: %s)\n", lscp_server_package(), lscp_server_version(), lscp_server_build()); - fputs("\n Available server commands: help, exit, quit, list", stdout); - fputs("\n (all else are broadcast verbatim to subscribers)\n\n", stdout); + fputs("\n Available server commands: help, exit, quit, list", stdout); + fputs("\n (all else are broadcast verbatim to subscribers)\n\n", stdout); } void server_prompt (void) { - fputs("lscp_server> ", stdout); + fputs("lscp_server> ", stdout); } int main (int argc, char *argv[] ) { - lscp_server_t *pServer; - char szLine[200]; - int cchLine; - lscp_connect_t *p; + lscp_server_t *pServer; + char szLine[200]; + int cchLine; + lscp_connect_t *p; #if defined(WIN32) - if (WSAStartup(MAKEWORD(1, 1), &_wsaData) != 0) { - fprintf(stderr, "lscp_server: WSAStartup failed.\n"); - return -1; - } + if (WSAStartup(MAKEWORD(1, 1), &_wsaData) != 0) { + fprintf(stderr, "lscp_server: WSAStartup failed.\n"); + return -1; + } #endif - srand(time(NULL)); + srand(time(NULL)); - pServer = lscp_server_create(SERVER_PORT, server_callback, NULL); - if (pServer == NULL) - return -1; - - server_usage(); - server_prompt(); - - while (fgets(szLine, sizeof(szLine), stdin)) { - - cchLine = strlen(szLine); - while (cchLine > 0 && (szLine[cchLine - 1] == '\n' || szLine[cchLine - 1] == '\r')) - cchLine--; - szLine[cchLine] = '\0'; - - if (strcmp(szLine, "exit") == 0 || strcmp(szLine, "quit") == 0) - break; - else - if (strcmp(szLine, "list") == 0) { - for (p = pServer->connects.first; p; p = p->next) { - printf("client: sock=%d addr=%s port=%d events=0x%04x.\n", - p->client.sock, - inet_ntoa(p->client.addr.sin_addr), - ntohs(p->client.addr.sin_port), - (int) p->events - ); - } - } - else - if (cchLine > 0 && strcmp(szLine, "help") != 0) - lscp_server_broadcast(pServer, LSCP_EVENT_MISCELLANEOUS, szLine, strlen(szLine)); - else - server_usage(); + pServer = lscp_server_create(SERVER_PORT, server_callback, NULL); + if (pServer == NULL) + return -1; + + server_usage(); + server_prompt(); + + while (fgets(szLine, sizeof(szLine), stdin)) { + + cchLine = strlen(szLine); + while (cchLine > 0 && (szLine[cchLine - 1] == '\n' || szLine[cchLine - 1] == '\r')) + cchLine--; + szLine[cchLine] = '\0'; + + if (strcmp(szLine, "exit") == 0 || strcmp(szLine, "quit") == 0) + break; + else + if (strcmp(szLine, "list") == 0) { + for (p = pServer->connects.first; p; p = p->next) { + printf("client: sock=%d addr=%s port=%d events=0x%04x.\n", + p->client.sock, + inet_ntoa(p->client.addr.sin_addr), + ntohs(p->client.addr.sin_port), + (int) p->events + ); + } + } + else + if (cchLine > 0 && strcmp(szLine, "help") != 0) + lscp_server_broadcast(pServer, LSCP_EVENT_MISCELLANEOUS, szLine, strlen(szLine)); + else + server_usage(); - server_prompt(); - } + server_prompt(); + } - lscp_server_destroy(pServer); + lscp_server_destroy(pServer); #if defined(WIN32) - WSACleanup(); + WSACleanup(); #endif - return 0; + return 0; } // end of example_server.c