/[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 1019 - (show annotations) (download)
Thu Jan 11 12:33:05 2007 UTC (17 years, 3 months ago) by capela
File MIME type: text/plain
File size: 26998 byte(s)
* Added new client interface functions, for sampler
  channel effect sends control:
	 lscp_create_fxsend();
	 lscp_destroy_fxsend();
	 lscp_get_fxsends();
	 lscp_list_fxsends();
	 lscp_get_fxsend_info();
	 lscp_set_fxsend_audio_channel();
  and for global volume:
	 lscp_get_volume();
	 lscp_set_volume();

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

  ViewVC Help
Powered by ViewVC