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

  ViewVC Help
Powered by ViewVC