/[svn]/liblscp/trunk/examples/example_server.c
ViewVC logotype

Contents of /liblscp/trunk/examples/example_server.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 946 - (show annotations) (download)
Mon Nov 27 18:33:02 2006 UTC (17 years, 5 months ago) by capela
File MIME type: text/plain
File size: 31176 byte(s)
* As of the LSCP 1.2 working draft document, added
  some missing client interface functions:
    lscp_get_total_voice_count();
    lscp_get_total_voice_count_max();
  and for the new MIDI instrument mapping features:
    lscp_map_midi_instrument();
    lscp_unmap_midi_instrument();
    lscp_get_midi_instruments();
    lscp_get_midi_instrument_info();
    lscp_clear_midi_instruments();

1 // example_server.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2006, rncbc aka Rui Nuno Capela. All rights reserved.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 *****************************************************************************/
22
23 #include "server.h"
24 #include "parser.h"
25
26 #include <time.h>
27
28 #define SERVER_PORT 8888
29
30 #if defined(WIN32)
31 static WSADATA _wsaData;
32 #endif
33
34 ////////////////////////////////////////////////////////////////////////
35
36 lscp_status_t server_callback ( lscp_connect_t *pConnect, const char *pchBuffer, int cchBuffer, void *pvData )
37 {
38 lscp_status_t ret = LSCP_OK;
39 lscp_parser_t tok;
40 const char *pszResult = NULL;
41 char szTemp[256];
42 int i;
43 static int iSamplerChannel = 0;
44 static int iAudioDevice = 0;
45 static int iMidiDevice = 0;
46 static int iMidiInstruments = 0;
47
48 if (pchBuffer == NULL) {
49 fprintf(stderr, "server_callback: addr=%s port=%d: ",
50 inet_ntoa(pConnect->client.addr.sin_addr),
51 htons(pConnect->client.addr.sin_port));
52 switch (cchBuffer) {
53 case LSCP_CONNECT_OPEN:
54 fprintf(stderr, "New client connection.\n");
55 break;
56 case LSCP_CONNECT_CLOSE:
57 fprintf(stderr, "Connection closed.\n");
58 break;
59 }
60 return ret;
61 }
62
63 lscp_socket_trace("server_callback", &(pConnect->client.addr), pchBuffer, cchBuffer);
64
65 lscp_parser_init(&tok, pchBuffer, cchBuffer);
66
67 if (lscp_parser_test(&tok, "GET")) {
68 if (lscp_parser_test(&tok, "CHANNEL")) {
69 if (lscp_parser_test(&tok, "INFO")) {
70 // Getting sampler channel informations:
71 // GET CHANNEL INFO <sampler-channel>
72 pszResult = "ENGINE_NAME: DummyEngine\r\n"
73 "INSTRUMENT_FILE: DummyInstrument.gig\r\n"
74 "INSTRUMENT_NR: 0\r\n"
75 "INSTRUMENT_NAME: Dummy Instrument\r\n"
76 "INSTRUMENT_STATUS: 100\r\n"
77 "AUDIO_OUTPUT_DEVICE: 0\r\n"
78 "AUDIO_OUTPUT_CHANNELS: 2\r\n"
79 "AUDIO_OUTPUT_ROUTING: 0,1\r\n"
80 "MIDI_INPUT_DEVICE: 0\r\n"
81 "MIDI_INPUT_PORT: 0\r\n"
82 "MIDI_INPUT_CHANNEL: ALL\r\n"
83 "VOLUME: 0.5\r\n"
84 "MUTE: FALSE\r\n"
85 "SOLO: TRUE\r\n";
86 }
87 else if (lscp_parser_test(&tok, "VOICE_COUNT")) {
88 // Current number of active voices:
89 // GET CHANNEL VOICE_COUNT <sampler-channel>
90 sprintf(szTemp, "%d", rand() % 100);
91 pszResult = szTemp;
92 }
93 else if (lscp_parser_test(&tok, "STREAM_COUNT")) {
94 // Current number of active disk streams:
95 // GET CHANNEL STREAM_COUNT <sampler-channel>
96 pszResult = "3\r\n";
97 }
98 else if (lscp_parser_test(&tok, "BUFFER_FILL")) {
99 if (lscp_parser_test(&tok, "BYTES")) {
100 // Current fill state of disk stream buffers:
101 // GET CHANNEL BUFFER_FILL BYTES <sampler-channel>
102 sprintf(szTemp, "[1]%d,[2]%d,[3]%d\r\n", rand(), rand(), rand());
103 pszResult = szTemp;
104 }
105 else if (lscp_parser_test(&tok, "PERCENTAGE")) {
106 // Current fill state of disk stream buffers:
107 // GET CHANNEL BUFFER_FILL PERCENTAGE <sampler-channel>
108 sprintf(szTemp, "[1]%d%%,[2]%d%%,[3]%d%%\r\n", rand() % 100, rand() % 100, rand() % 100);
109 pszResult = szTemp;
110 }
111 else ret = LSCP_FAILED;
112 }
113 else ret = LSCP_FAILED;
114 }
115 else if (lscp_parser_test(&tok, "CHANNELS")) {
116 // Current number of sampler channels:
117 // GET CHANNELS
118 sprintf(szTemp, "%d", iSamplerChannel);
119 pszResult = szTemp;
120 }
121 else if (lscp_parser_test(&tok, "AVAILABLE_AUDIO_OUTPUT_DRIVERS")) {
122 // Getting all available audio output driver count.
123 // GET AVAILABLE_AUDIO_OUTPUT_DRIVERS
124 pszResult = "2\r\n";
125 }
126 else if (lscp_parser_test(&tok, "AVAILABLE_MIDI_INPUT_DRIVERS")) {
127 // Getting all available MIDI input driver count.
128 // GET AVAILABLE_MIDI_INPUT_DRIVERS
129 pszResult = "1\r\n";
130 }
131 else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER", "INFO")) {
132 // Getting informations about a specific audio output driver.
133 // GET AUDIO_OUTPUT_DRIVER INFO <audio-output-type>
134 if (lscp_parser_test(&tok, "Alsa")) {
135 pszResult = "DESCRIPTION: 'ALSA PCM'\r\n"
136 "VERSION: '1.0'\r\n"
137 "PARAMETERS: channels,samplerate,active\r\n";
138 }
139 else if (lscp_parser_test(&tok, "Jack")) {
140 pszResult = "DESCRIPTION: JACK Audio Connection Kit\r\n"
141 "VERSION: 0.98.1\r\n"
142 "PARAMETERS: channels,samplerate,active\r\n";
143 }
144 else ret = LSCP_FAILED;
145 }
146 else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER", "INFO")) {
147 // Getting informations about a specific MIDI input driver.
148 // GET MIDI_INPUT_DRIVER INFO <midi-input-type>
149 if (lscp_parser_test(&tok, "Alsa")) {
150 pszResult = "DESCRIPTION: ALSA Sequencer\r\n"
151 "VERSION: 1.0\r\n"
152 "PARAMETERS: ports,active\r\n";
153 }
154 else ret = LSCP_FAILED;
155 }
156 else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER_PARAMETER", "INFO")) {
157 // Getting informations about a specific audio output driver parameter.
158 // GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO <audio-output-type> <param>
159 if (lscp_parser_test(&tok, "Alsa")) {
160 if (lscp_parser_test(&tok, "active")) {
161 pszResult = "DESCRIPTION: 'ALSA PCM active state'\r\n"
162 "TYPE: BOOL\r\n"
163 "MANDATORY: TRUE\r\n"
164 "FIX: TRUE\r\n"
165 "MULTIPLICITY: FALSE\r\n"
166 "DEPENDS: channels,samplerate,card\r\n"
167 "DEFAULT: TRUE\r\n"
168 "RANGE_MIN: FALSE\r\n"
169 "RANGE_MAX: TRUE\r\n"
170 "POSSIBILITIES: FALSE,TRUE\r\n";
171 }
172 else if (lscp_parser_test(&tok, "channels")) {
173 pszResult = "DESCRIPTION: 'Number of ALSA PCM channels'\r\n"
174 "TYPE: INT\r\n"
175 "MANDATORY: TRUE\r\n"
176 "FIX: TRUE\r\n"
177 "MULTIPLICITY: FALSE\r\n"
178 "DEFAULT: 2\r\n";
179 }
180 else if (lscp_parser_test(&tok, "samplerate")) {
181 pszResult = "DESCRIPTION: 'ALSA PCM sample rate'\r\n"
182 "TYPE: INT\r\n"
183 "MANDATORY: TRUE\r\n"
184 "FIX: TRUE\r\n"
185 "MULTIPLICITY: TRUE\r\n"
186 "DEFAULT: 44100\r\n"
187 "POSSIBILITIES: 44100,48000,96000\r\n";
188 }
189 else ret = LSCP_FAILED;
190 }
191 else if (lscp_parser_test(&tok, "Jack")) {
192 if (lscp_parser_test(&tok, "active")) {
193 pszResult = "DESCRIPTION: 'JACK active state'\r\n"
194 "TYPE: BOOL\r\n"
195 "MANDATORY: TRUE\r\n"
196 "FIX: TRUE\r\n"
197 "MULTIPLICITY: FALSE\r\n"
198 "DEPENDS: channels,samplerate\r\n"
199 "DEFAULT: TRUE\r\n"
200 "RANGE_MIN: FALSE\r\n"
201 "RANGE_MAX: TRUE\r\n"
202 "POSSIBILITIES: FALSE,TRUE\r\n";
203 }
204 else if (lscp_parser_test(&tok, "channels")) {
205 pszResult = "DESCRIPTION: 'Number of JACK audio channels'\r\n"
206 "TYPE: INT\r\n"
207 "MANDATORY: TRUE\r\n"
208 "FIX: TRUE\r\n"
209 "MULTIPLICITY: FALSE\r\n"
210 "DEFAULT: 2\r\n";
211 }
212 else if (lscp_parser_test(&tok, "samplerate")) {
213 pszResult = "DESCRIPTION: 'JACK sample rate'\r\n"
214 "TYPE: INT\r\n"
215 "MANDATORY: TRUE\r\n"
216 "FIX: TRUE\r\n"
217 "MULTIPLICITY: TRUE\r\n"
218 "DEFAULT: 44100\r\n"
219 "POSSIBILITIES: 44100,48000,96000\r\n";
220 }
221 else ret = LSCP_FAILED;
222 }
223 else ret = LSCP_FAILED;
224 }
225 else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER_PARAMETER", "INFO")) {
226 // Getting informations about a specific MIDI input driver parameter.
227 // GET MIDI_INPUT_DRIVER_PARAMETER INFO <midi-input-type> <param>
228 if (lscp_parser_test(&tok, "Alsa")) {
229 if (lscp_parser_test(&tok, "active")) {
230 pszResult = "DESCRIPTION: 'ALSA Sequencer device active state'\r\n"
231 "TYPE: BOOL\r\n"
232 "MANDATORY: TRUE\r\n"
233 "FIX: TRUE\r\n"
234 "MULTIPLICITY: FALSE\r\n"
235 "DEPENDS: channels,ports\r\n"
236 "DEFAULT: TRUE\r\n"
237 "RANGE_MIN: FALSE\r\n"
238 "RANGE_MAX: TRUE\r\n"
239 "POSSIBILITIES: FALSE,TRUE\r\n";
240 }
241 else if (lscp_parser_test(&tok, "ports")) {
242 pszResult = "DESCRIPTION: 'Number of ALSA Sequencer ports'\r\n"
243 "TYPE: INT\r\n"
244 "MANDATORY: FALSE\r\n"
245 "FIX: FALSE\r\n"
246 "MULTIPLICITY: FALSE\r\n"
247 "DEFAULT: 1\r\n"
248 "RANGE_MIN: 1\r\n"
249 "RANGE_MAX: 4\r\n";
250 }
251 else ret = LSCP_FAILED;
252 }
253 else ret = LSCP_FAILED;
254 }
255 else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DEVICE", "INFO")) {
256 // Getting informations about a specific audio output device.
257 // GET AUDIO_OUTPUT_DEVICE INFO <audio-device-id>
258 if (lscp_parser_nextint(&tok) < iAudioDevice) {
259 pszResult = "driver: Alsa\r\n"
260 "active: TRUE\r\n"
261 "channels: 2\r\n"
262 "samplerate: 44100\r\n";
263 }
264 else ret = LSCP_FAILED;
265 }
266 else if (lscp_parser_test2(&tok, "MIDI_INPUT_DEVICE", "INFO")) {
267 // Getting informations about a specific MIDI input device.
268 // GET MIDI_INPUT_DEVICE INFO <midi-device-id>
269 if (lscp_parser_nextint(&tok) < iMidiDevice) {
270 pszResult = "driver: Alsa\r\n"
271 "active: TRUE\r\n"
272 "channels: 16\r\n"
273 "ports: 1\r\n";
274 }
275 else ret = LSCP_FAILED;
276 }
277 else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_CHANNEL", "INFO")) {
278 // Getting informations about an audio channel.
279 // GET AUDIO_OUTPUT_CHANNEL INFO <audio-device-id> <audio-channel>
280 if (lscp_parser_nextint(&tok) < iAudioDevice) {
281 pszResult = "name: DummyMonitor\r\n"
282 "is_mix_channel: FALSE\r\n"
283 "mix_channel_destination: 0\r\n";
284 }
285 else ret = LSCP_FAILED;
286 }
287 else if (lscp_parser_test2(&tok, "MIDI_INPUT_PORT", "INFO")) {
288 // Getting informations about a MIDI port.
289 // GET MIDI_INPUT_PORT INFO <midi-device-id> <midi-port>
290 if (lscp_parser_nextint(&tok) < iMidiDevice) {
291 pszResult = "name: DummyKeyboard\r\n"
292 "alsa_seq_bindings: '64:0'\r\n";
293 }
294 else ret = LSCP_FAILED;
295 }
296 else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_CHANNEL_PARAMETER", "INFO")) {
297 // Getting informations about specific audio channel parameter.
298 // GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO <audio-device-id> <audio-channel> <param>
299 if (lscp_parser_nextint(&tok) < iAudioDevice) {
300 lscp_parser_nextint(&tok);
301 if (lscp_parser_test(&tok, "is_mix_channel")) {
302 pszResult = "DESCRIPTION: 'Whether this is an audio mix channel'\r\n"
303 "TYPE: BOOL\r\n"
304 "MANDATORY: TRUE\r\n"
305 "FIX: FALSE\r\n"
306 "MULTIPLICITY: FALSE\r\n"
307 "POSSIBILITIES: FALSE,TRUE\r\n";
308 }
309 else if (lscp_parser_test(&tok, "mix_channel_destination")) {
310 pszResult = "DESCRIPTION: 'Audio mix channel destination'\r\n"
311 "TYPE: INT\r\n"
312 "MANDATORY: TRUE\r\n"
313 "FIX: FALSE\r\n"
314 "MULTIPLICITY: TRUE\r\n"
315 "POSSIBILITIES: 0,1\r\n";
316 }
317 else ret = LSCP_FAILED;
318 }
319 else ret = LSCP_FAILED;
320 }
321 else if (lscp_parser_test2(&tok, "MIDI_INPUT_PORT_PARAMETER", "INFO")) {
322 // Getting informations about specific MIDI port parameter.
323 // GET MIDI_INPUT_PORT_PARAMETER INFO <midi-device-id> <midi-port> <param>
324 if (lscp_parser_nextint(&tok) < iMidiDevice) {
325 lscp_parser_nextint(&tok);
326 if (lscp_parser_test(&tok, "alsa_seq_bindings")) {
327 pszResult = "DESCRIPTION: 'Alsa sequencer port bindings'\r\n"
328 "TYPE: STRING\r\n"
329 "MANDATORY: TRUE\r\n"
330 "FIX: FALSE\r\n"
331 "MULTIPLICITY: TRUE\r\n"
332 "POSSIBILITIES: '64:0','68:0','68:1'\r\n";
333 }
334 else ret = LSCP_FAILED;
335 }
336 else ret = LSCP_FAILED;
337 }
338 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICES")) {
339 // Getting all created audio output device count.
340 // GET AUDIO_OUTPUT_DEVICES
341 sprintf(szTemp, "%d\r\n", iAudioDevice);
342 pszResult = szTemp;
343 }
344 else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICES")) {
345 // Getting all created MID input device count.
346 // GET MIDI_INPUT_DEVICES
347 sprintf(szTemp, "%d\r\n", iMidiDevice);
348 pszResult = szTemp;
349 }
350 else if (lscp_parser_test(&tok, "AVAILABLE_ENGINES")) {
351 // Getting all available engine count:
352 // GET AVAILABLE_ENGINES
353 pszResult = "3\r\n";
354 }
355 else if (lscp_parser_test2(&tok, "SERVER", "INFO")) {
356 // Getting information about the server.
357 // GET SERVER INFO
358 sprintf(szTemp, "DESCRIPTION: example_server (%s) %s\r\n"
359 "VERSION: %s\r\n", lscp_server_package(),
360 lscp_server_build(), lscp_server_version());
361 pszResult = szTemp;
362 }
363 else if (lscp_parser_test2(&tok, "ENGINE", "INFO")) {
364 // Getting information about an engine.
365 // GET ENGINE INFO <engine-name>
366 if (lscp_parser_test(&tok, "GigEngine")) {
367 pszResult = "DESCRIPTION: GigaSampler Engine\r\n"
368 "VERSION: 0.3\r\n";
369 }
370 else if (lscp_parser_test(&tok, "DLSEngine")) {
371 pszResult = "DESCRIPTION: 'DLS Generic Engine'\r\n"
372 "VERSION: 0.2\r\n";
373 }
374 else if (lscp_parser_test(&tok, "AkaiEngine")) {
375 pszResult = "DESCRIPTION: Akai Sampler Engine\r\n"
376 "VERSION: 0.1\r\n";
377 }
378 else ret = LSCP_FAILED;
379 }
380 else if (lscp_parser_test(&tok, "TOTAL_VOICE_COUNT")) {
381 // Current number of active voices:
382 // GET TOTAL_VOICE_COUNT
383 sprintf(szTemp, "%d", rand() % 100);
384 pszResult = szTemp;
385 }
386 else if (lscp_parser_test(&tok, "TOTAL_VOICE_COUNT_MAX")) {
387 // Maximum amount of active voices:
388 // GET TOTAL_VOICE_COUNT_MAX
389 sprintf(szTemp, "%d", rand() % 100);
390 pszResult = szTemp;
391 }
392 else if (lscp_parser_test(&tok, "MIDI_INSTRUMENTS")) {
393 // Get the total count of MIDI instrument map entries:
394 // GET MIDI_INSTRUMENTS
395 sprintf(szTemp, "%d", iMidiInstruments);
396 pszResult = szTemp;
397 }
398 if (lscp_parser_test2(&tok, "MIDI_INSTRUMENT", "INFO")) {
399 // Getting information about a MIDI instrument map entry:
400 // GET MIDI_INSTRUMENT INFO <midi-bank-msb> <midi-bank-lsb> <midi-prog>
401 pszResult = "NAME: DummyName\r\n"
402 "ENGINE_NAME: DummyEngine\r\n"
403 "INSTRUMENT_FILE: DummyInstrument.gig\r\n"
404 "INSTRUMENT_NR: 0\r\n"
405 "INSTRUMENT_NAME: Dummy Instrument\r\n"
406 "LOAD_MODE: ON_DEMAND\r\n"
407 "VOLUME: 0.5\r\n";
408 }
409 else ret = LSCP_FAILED;
410 }
411 else if (lscp_parser_test(&tok, "LIST")) {
412 if (lscp_parser_test(&tok, "CHANNELS")) {
413 // Getting all created sampler channel list.
414 // LIST CHANNELS
415 if (iSamplerChannel > 0) {
416 strcpy(szTemp, "0");
417 for (i = 1; i < iSamplerChannel && strlen(szTemp) < sizeof(szTemp) - 8; i++)
418 sprintf(szTemp + strlen(szTemp), ",%d", i);
419 strcat(szTemp, "\r\n");
420 pszResult = szTemp;
421 }
422 else ret = LSCP_FAILED;
423 }
424 else if (lscp_parser_test(&tok, "AVAILABLE_ENGINES")) {
425 // Getting all available engines:
426 // LIST AVAILABLE_ENGINES
427 pszResult = "GigEngine,DLSEngine,AkaiEngine\r\n";
428 }
429 else if (lscp_parser_test(&tok, "AVAILABLE_AUDIO_OUTPUT_DRIVERS")) {
430 // Getting all available audio output drivers.
431 // LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS
432 pszResult = "ALSA,JACK\r\n";
433 }
434 else if (lscp_parser_test(&tok, "AVAILABLE_MIDI_INPUT_DRIVERS")) {
435 // Getting all available MIDI input drivers.
436 // LIST AVAILABLE_MIDI_INPUT_DRIVERS
437 pszResult = "ALSA\r\n";
438 }
439 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICES")) {
440 // Getting all created audio output device list.
441 // LIST AUDIO_OUTPUT_DEVICES
442 if (iAudioDevice > 0) {
443 strcpy(szTemp, "0");
444 for (i = 1; i < iAudioDevice && strlen(szTemp) < sizeof(szTemp) - 8; i++)
445 sprintf(szTemp + strlen(szTemp), ",%d", i);
446 strcat(szTemp, "\r\n");
447 pszResult = szTemp;
448 }
449 else ret = LSCP_FAILED;
450 }
451 else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICES")) {
452 // Getting all created MID input device list.
453 // LIST MIDI_INPUT_DEVICES
454 if (iMidiDevice > 0) {
455 strcpy(szTemp, "0");
456 for (i = 1; i < iMidiDevice && strlen(szTemp) < sizeof(szTemp) - 8; i++)
457 sprintf(szTemp + strlen(szTemp), ",%d", i);
458 strcat(szTemp, "\r\n");
459 pszResult = szTemp;
460 }
461 else ret = LSCP_FAILED;
462 }
463 else if (lscp_parser_test(&tok, "LIST_MIDI_INSTRUMENTS")) {
464 // Getting indeces of all MIDI instrument map entries:
465 // LIST MIDI_INSTRUMENTS
466 if (iMidiInstruments > 0) {
467 strcpy(szTemp, "{0,0,0}");
468 for (i = 1; i < iMidiInstruments && strlen(szTemp) < sizeof(szTemp) - 16; i++)
469 sprintf(szTemp + strlen(szTemp), ",{0,%d,%d}", i / 128, i % 128);
470 strcat(szTemp, "\r\n");
471 pszResult = szTemp;
472 }
473 else ret = LSCP_FAILED;
474 }
475 else ret = LSCP_FAILED;
476 }
477 else if (lscp_parser_test(&tok, "SET")) {
478 if (lscp_parser_test(&tok, "CHANNEL")) {
479 if (lscp_parser_test(&tok, "VOLUME")) {
480 // Setting channel volume:
481 // SET CHANNEL VOLUME <sampler-channel> <volume>
482 }
483 else if (lscp_parser_test(&tok, "MUTE")) {
484 // Muting a sampler channel:
485 // SET CHANNEL MUTE <sampler-channel> <mute>
486 }
487 else if (lscp_parser_test(&tok, "SOLO")) {
488 // Soloing a sampler channel:
489 // SET CHANNEL SOLO <sampler-channel> <solo>
490 }
491 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_TYPE")) {
492 // Setting audio output type:
493 // SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
494 }
495 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) {
496 // Setting audio output device:
497 // SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
498 }
499 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_CHANNEL")) {
500 // Setting audio output channel:
501 // SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-in> <audio-out>
502 }
503 else if (lscp_parser_test(&tok, "MIDI_INPUT_TYPE")) {
504 // Setting MIDI input type:
505 // SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
506 }
507 else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) {
508 // Setting MIDI input device:
509 // SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
510 }
511 else if (lscp_parser_test(&tok, "MIDI_INPUT_PORT")) {
512 // Setting MIDI input port:
513 // SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
514 }
515 else if (lscp_parser_test(&tok, "MIDI_INPUT_CHANNEL")) {
516 // Setting MIDI input channel:
517 // SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
518 }
519 else ret = LSCP_FAILED;
520 }
521 else ret = LSCP_FAILED;
522 }
523 else if (lscp_parser_test(&tok, "LOAD")) {
524 if (lscp_parser_test(&tok, "ENGINE")) {
525 // Loading a sampler engine:
526 // LOAD ENGINE <engine-name> <sampler-channel>
527 }
528 else if (lscp_parser_test(&tok, "INSTRUMENT")) {
529 // Loading an instrument:
530 // LOAD INSTRUMENT [NON_MODAL] <filename> <instr-index> <sampler-channel>
531 }
532 else ret = LSCP_FAILED;
533 }
534 else if (lscp_parser_test2(&tok, "ADD", "CHANNEL")) {
535 // Adding a new sampler channel:
536 // ADD CHANNEL
537 if (iSamplerChannel < 16) {
538 sprintf(szTemp, "OK[%d]", iSamplerChannel++);
539 pszResult = szTemp;
540 } else {
541 iSamplerChannel = 0;
542 ret = LSCP_FAILED;
543 }
544 }
545 else if (lscp_parser_test2(&tok, "REMOVE", "CHANNEL")) {
546 // Removing a sampler channel:
547 // REMOVE CHANNEL <sampler-channel>
548 if (lscp_parser_nextint(&tok) < iSamplerChannel)
549 iSamplerChannel--;
550 else
551 ret = LSCP_FAILED;
552 }
553 else if (lscp_parser_test(&tok, "RESET")) {
554 if (lscp_parser_test(&tok, "CHANNEL")) {
555 // Resetting a sampler channel:
556 // RESET CHANNEL <sampler-channel>
557 if (lscp_parser_nextint(&tok) > iSamplerChannel)
558 ret = LSCP_FAILED;
559 } else {
560 // Reset sampler:
561 // RESET
562 iSamplerChannel = 0;
563 iAudioDevice = 0;
564 iMidiDevice = 0;
565 }
566 }
567 else if (lscp_parser_test(&tok, "CREATE")) {
568 if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) {
569 // Creating an audio output device.
570 // CREATE AUDIO_OUTPUT_DEVICE <audio-output-driver> [<params>]
571 if (iAudioDevice < 8) {
572 sprintf(szTemp, "OK[%d]", iAudioDevice++);
573 pszResult = szTemp;
574 } else {
575 iAudioDevice = 0;
576 ret = LSCP_FAILED;
577 }
578 }
579 else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) {
580 // Creating an MIDI input device.
581 // CREATE MIDI_INPUT_DEVICE <midi-input-driver> [<params>]
582 if (iMidiDevice < 8) {
583 sprintf(szTemp, "OK[%d]", iMidiDevice++);
584 pszResult = szTemp;
585 } else {
586 iMidiDevice = 0;
587 ret = LSCP_FAILED;
588 }
589 }
590 else ret = LSCP_FAILED;
591 }
592 else if (lscp_parser_test(&tok, "DESTROY")) {
593 if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) {
594 // Destroying an audio output device.
595 // DESTROY AUDIO_OUTPUT_DEVICE <audio-device-id>
596 if (lscp_parser_nextint(&tok) < iAudioDevice)
597 iAudioDevice--;
598 else
599 ret = LSCP_FAILED;
600 }
601 else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) {
602 // Destroying an MIDI intput device.
603 // DESTROY MIDI_INPUT_DEVICE <midi-device-id>
604 if (lscp_parser_nextint(&tok) < iMidiDevice)
605 iMidiDevice--;
606 else
607 ret = LSCP_FAILED;
608 }
609 else ret = LSCP_FAILED;
610 }
611 else if (lscp_parser_test2(&tok, "MAP", "MIDI_INSTRUMENT")) {
612 // Create or replace a MIDI instrumnet map entry:
613 // MAP MIDI_INSTRUMENT <midi-bank-msb> <midi-bank-lsb> <midi-prog>
614 // <engine-name> <filename> <instr-index> <volume> <load-mode> [<name>]
615 iMidiInstruments++;
616 }
617 else if (lscp_parser_test2(&tok, "UNMAP", "MIDI_INSTRUMENT")) {
618 // Remove an entry from the MIDI instrument map:
619 // UNMAP MIDI_INSTRUMENT <midi-bank-msb> <midi-bank-lsb> <midi-prog>
620 if (iMidiInstruments > 0)
621 iMidiInstruments--;
622 else
623 ret = LSCP_FAILED;
624 }
625 else if (lscp_parser_test2(&tok, "CLEAR", "MIDI_INSTRUMENTS")) {
626 // Clear the MIDI instrumnet map:
627 // CLEAR MIDI_INSTRUMENTS
628 }
629 else if (lscp_parser_test(&tok, "SUBSCRIBE")) {
630 // Register frontend for receiving event notification messages:
631 // SUBSCRIBE <event>
632 ret = lscp_server_subscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok)));
633 }
634 else if (lscp_parser_test(&tok, "UNSUBSCRIBE")) {
635 // Deregister frontend for not receiving event notification messages anymore:
636 // UNSUBSCRIBE <event>
637 ret = lscp_server_unsubscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok)));
638 }
639 else if (lscp_parser_test(&tok, "QUIT")) {
640 // Close client connection:
641 // QUIT
642 lscp_parser_free(&tok);
643 return LSCP_FAILED; // Disconnect.
644 }
645 else ret = LSCP_FAILED;
646
647 lscp_parser_free(&tok);
648
649 if (pszResult == NULL)
650 pszResult = (ret == LSCP_OK ? "OK\r\n" : "ERR:1:Failed\r\n");
651
652 fprintf(stderr, "> %s", pszResult);
653
654 return lscp_server_result(pConnect, pszResult, strlen(pszResult));
655 }
656
657 ////////////////////////////////////////////////////////////////////////
658
659
660 void server_usage (void)
661 {
662 printf("\n %s %s (Build: %s)\n", lscp_server_package(), lscp_server_version(), lscp_server_build());
663
664 fputs("\n Available server commands: help, exit, quit, list", stdout);
665 fputs("\n (all else are broadcast verbatim to subscribers)\n\n", stdout);
666 }
667
668 void server_prompt (void)
669 {
670 fputs("lscp_server> ", stdout);
671 }
672
673 int main (int argc, char *argv[] )
674 {
675 lscp_server_t *pServer;
676 char szLine[200];
677 int cchLine;
678 lscp_connect_t *p;
679
680 #if defined(WIN32)
681 if (WSAStartup(MAKEWORD(1, 1), &_wsaData) != 0) {
682 fprintf(stderr, "lscp_server: WSAStartup failed.\n");
683 return -1;
684 }
685 #endif
686
687 srand(time(NULL));
688
689 pServer = lscp_server_create(SERVER_PORT, server_callback, NULL);
690 if (pServer == NULL)
691 return -1;
692
693 server_usage();
694 server_prompt();
695
696 while (fgets(szLine, sizeof(szLine), stdin)) {
697
698 cchLine = strlen(szLine);
699 while (cchLine > 0 && (szLine[cchLine - 1] == '\n' || szLine[cchLine - 1] == '\r'))
700 cchLine--;
701 szLine[cchLine] = '\0';
702
703 if (strcmp(szLine, "exit") == 0 || strcmp(szLine, "quit") == 0)
704 break;
705 else
706 if (strcmp(szLine, "list") == 0) {
707 for (p = pServer->connects.first; p; p = p->next) {
708 printf("client: sock=%d addr=%s port=%d events=0x%04x.\n",
709 p->client.sock,
710 inet_ntoa(p->client.addr.sin_addr),
711 ntohs(p->client.addr.sin_port),
712 (int) p->events
713 );
714 }
715 }
716 else
717 if (cchLine > 0 && strcmp(szLine, "help") != 0)
718 lscp_server_broadcast(pServer, LSCP_EVENT_MISCELLANEOUS, szLine, strlen(szLine));
719 else
720 server_usage();
721
722 server_prompt();
723 }
724
725 lscp_server_destroy(pServer);
726
727 #if defined(WIN32)
728 WSACleanup();
729 #endif
730
731 return 0;
732 }
733
734 // end of example_server.c

  ViewVC Help
Powered by ViewVC