/[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 963 - (show annotations) (download)
Sun Dec 3 18:30:04 2006 UTC (17 years, 3 months ago) by capela
File MIME type: text/plain
File size: 24490 byte(s)
* MIDI instrument mapping fixed, previously missing
  the regular ON_DEMAND load mode.

* Server error reporting is now effective; all server
  numerical error and warning codes are added to 100,
  thus giving a proper non-zero lscp_client_get_errno()
  return value.

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

  ViewVC Help
Powered by ViewVC