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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 163 - (hide annotations) (download)
Wed Jun 30 15:16:03 2004 UTC (19 years, 9 months ago) by capela
File MIME type: text/plain
File size: 16512 byte(s)
Driver parameter info wrapper implementation.

1 capela 105 // example_server.c
2     //
3     /****************************************************************************
4     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.
5    
6     This program is free software; you can redistribute it and/or
7     modify it under the terms of the GNU General Public License
8     as published by the Free Software Foundation; either version 2
9     of the License, or (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19    
20     *****************************************************************************/
21    
22     #include "server.h"
23     #include "parser.h"
24    
25     #include <time.h>
26    
27     #define SERVER_PORT 8888
28    
29     #if defined(WIN32)
30     static WSADATA _wsaData;
31     #endif
32    
33     ////////////////////////////////////////////////////////////////////////
34    
35     lscp_status_t server_callback ( lscp_connect_t *pConnect, const char *pchBuffer, int cchBuffer, void *pvData )
36     {
37     lscp_status_t ret = LSCP_OK;
38     lscp_parser_t tok;
39     const char *pszResult = NULL;
40     char szTemp[256];
41 capela 125 int i;
42 capela 105 static int iChannel = 0;
43    
44     if (pchBuffer == NULL) {
45     fprintf(stderr, "server_callback: addr=%s port=%d: ",
46     inet_ntoa(pConnect->client.addr.sin_addr),
47     htons(pConnect->client.addr.sin_port));
48     switch (cchBuffer) {
49     case LSCP_CONNECT_OPEN:
50     fprintf(stderr, "New client connection.\n");
51     break;
52     case LSCP_CONNECT_CLOSE:
53     fprintf(stderr, "Connection closed.\n");
54     break;
55     }
56     return ret;
57     }
58    
59     lscp_socket_trace("server_callback", &(pConnect->client.addr), pchBuffer, cchBuffer);
60    
61     lscp_parser_init(&tok, pchBuffer, cchBuffer);
62    
63     if (lscp_parser_test(&tok, "GET")) {
64     if (lscp_parser_test(&tok, "CHANNEL")) {
65     if (lscp_parser_test(&tok, "INFO")) {
66     // Getting sampler channel informations:
67     // GET CHANNEL INFO <sampler-channel>
68     pszResult = "ENGINE_NAME: DummyEngine\r\n"
69     "INSTRUMENT_FILE: DummyInstrument.gig\r\n"
70     "INSTRUMENT_NR: 0\r\n"
71 capela 144 "INSTRUMENT_STATUS: 100\r\n"
72 capela 105 "AUDIO_OUTPUT_DEVICE: 0\r\n"
73     "AUDIO_OUTPUT_CHANNELS: 2\r\n"
74     "AUDIO_OUTPUT_ROUTING: 0,1\r\n"
75     "MIDI_INPUT_DEVICE: 0\r\n"
76     "MIDI_INPUT_PORT: 0\r\n"
77     "MIDI_INPUT_CHANNEL: ALL\r\n"
78     "VOLUME: 0.5\r\n";
79     }
80     else if (lscp_parser_test(&tok, "VOICE_COUNT")) {
81     // Current number of active voices:
82     // GET CHANNEL VOICE_COUNT <sampler-channel>
83     sprintf(szTemp, "%d", rand() % 100);
84     pszResult = szTemp;
85     }
86     else if (lscp_parser_test(&tok, "STREAM_COUNT")) {
87     // Current number of active disk streams:
88     // GET CHANNEL STREAM_COUNT <sampler-channel>
89     pszResult = "3\r\n";
90     }
91     else if (lscp_parser_test(&tok, "BUFFER_FILL")) {
92     if (lscp_parser_test(&tok, "BYTES")) {
93     // Current fill state of disk stream buffers:
94     // GET CHANNEL BUFFER_FILL BYTES <sampler-channel>
95     sprintf(szTemp, "[1]%d,[2]%d,[3]%d\r\n", rand(), rand(), rand());
96     pszResult = szTemp;
97     }
98     else if (lscp_parser_test(&tok, "PERCENTAGE")) {
99     // Current fill state of disk stream buffers:
100     // GET CHANNEL BUFFER_FILL PERCENTAGE <sampler-channel>
101     sprintf(szTemp, "[1]%d%%,[2]%d%%,[3]%d%%\r\n", rand() % 100, rand() % 100, rand() % 100);
102     pszResult = szTemp;
103     }
104     else ret = LSCP_FAILED;
105     }
106     else ret = LSCP_FAILED;
107     }
108     else if (lscp_parser_test(&tok, "CHANNELS")) {
109     // Current number of sampler channels:
110     // GET CHANNELS
111     sprintf(szTemp, "%d", iChannel);
112     pszResult = szTemp;
113     }
114     else if (lscp_parser_test(&tok, "AVAILABLE_AUDIO_OUTPUT_DRIVERS")) {
115     // Getting all available audio output drivers.
116     // GET AVAILABLE_AUDIO_OUTPUT_DRIVERS
117 capela 144 pszResult = "Alsa,Jack,CoreAudio\r\n";
118 capela 105 }
119     else if (lscp_parser_test(&tok, "AVAILABLE_MIDI_INPUT_DRIVERS")) {
120     // Getting all available MIDI input drivers.
121     // GET AVAILABLE_MIDI_INPUT_DRIVERS
122 capela 144 pszResult = "Alsa,MidiShare,CoreMidi\r\n";
123 capela 105 }
124     else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER", "INFO")) {
125     // Getting informations about a specific audio output driver.
126     // GET AUDIO_OUTPUT_DRIVER INFO <audio-output-type>
127 capela 163 if (lscp_parser_test(&tok, "Alsa")) {
128 capela 105 pszResult = "DESCRIPTION: 'ALSA PCM'\r\n"
129     "VERSION: '1.0'\r\n"
130 capela 163 "PARAMETERS: channels,samplerate,active,card\r\n";
131 capela 105 }
132 capela 163 else if (lscp_parser_test(&tok, "Jack")) {
133     pszResult = "DESCRIPTION: JACK Audio Connection Kit\r\n"
134 capela 105 "VERSION: 0.98.1\r\n"
135 capela 163 "PARAMETERS: channels,samplerate,active\r\n";
136 capela 105 }
137     else ret = LSCP_FAILED;
138     }
139     else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER", "INFO")) {
140     // Getting informations about a specific MIDI input driver.
141     // GET MIDI_INPUT_DRIVER INFO <midi-input-type>
142 capela 163 if (lscp_parser_test(&tok, "Alsa")) {
143 capela 105 pszResult = "DESCRIPTION: ALSA Sequencer\r\n"
144     "VERSION: 1.0\r\n"
145 capela 163 "PARAMETERS: ports,active\r\n";
146 capela 105 }
147     else ret = LSCP_FAILED;
148     }
149 capela 163 else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER_PARAMETER", "INFO")) {
150     // Getting informations about a specific audio output driver parameter.
151     // GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO <audio-output-type> <param>
152     if (lscp_parser_test2(&tok, "Alsa", "active")) {
153     pszResult = "DESCRIPTION: 'ALSA PCM device active state'\r\n"
154     "TYPE: BOOL\r\n"
155     "MANDATORY: TRUE\r\n"
156     "FIX: TRUE\r\n"
157     "MULTIPLICITY: FALSE\r\n"
158     "DEPENDS: channels,samplerate,card\r\n"
159     "DEFAULT: TRUE\r\n"
160     "RANGE_MIN: FALSE\r\n"
161     "RANGE_MIN: TRUE\r\n"
162     "POSSIBILITIES: FALSE,TRUE\r\n";
163     }
164     else if (lscp_parser_test2(&tok, "Jack", "active")) {
165     pszResult = "DESCRIPTION: 'JACK device 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\r\n"
171     "DEFAULT: TRUE\r\n"
172     "RANGE_MIN: FALSE\r\n"
173     "RANGE_MIN: TRUE\r\n"
174     "POSSIBILITIES: FALSE,TRUE\r\n";
175     }
176     else ret = LSCP_FAILED;
177     }
178     else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER_PARAMETER", "INFO")) {
179     // Getting informations about a specific MIDI input driver parameter.
180     // GET MIDI_INPUT_DRIVER_PARAMETER INFO <midi-input-type> <param>
181     if (lscp_parser_test2(&tok, "Alsa", "active")) {
182     pszResult = "DESCRIPTION: 'ALSA Sequencer device active state'\r\n"
183     "TYPE: BOOL\r\n"
184     "MANDATORY: TRUE\r\n"
185     "FIX: TRUE\r\n"
186     "MULTIPLICITY: FALSE\r\n"
187     "DEPENDS: channels,ports\r\n"
188     "DEFAULT: TRUE\r\n"
189     "RANGE_MIN: FALSE\r\n"
190     "RANGE_MIN: TRUE\r\n"
191     "POSSIBILITIES: FALSE,TRUE\r\n";
192     }
193     else ret = LSCP_FAILED;
194     }
195 capela 105 else if (lscp_parser_test(&tok, "AVAILABLE_ENGINES")) {
196     // Getting all available engines:
197     // GET AVAILABLE_ENGINES
198 capela 163 pszResult = "GigEngine,DLSEngine,AkaiEngine\r\n";
199 capela 105 }
200     else if (lscp_parser_test2(&tok, "ENGINE", "INFO")) {
201     // Getting information about an engine.
202     // GET ENGINE INFO <engine-name>
203 capela 163 if (lscp_parser_test(&tok, "GigEngine")) {
204     pszResult = "DESCRIPTION: GigaSampler Engine\r\n"
205     "VERSION: 0.3\r\n";
206     }
207     else if (lscp_parser_test(&tok, "DLSEngine")) {
208     pszResult = "DESCRIPTION: 'DLS Generic Engine'\r\n"
209     "VERSION: 0.2\r\n";
210     }
211     else if (lscp_parser_test(&tok, "AkaiEngine")) {
212     pszResult = "DESCRIPTION: Akai Sampler Engine\r\n"
213     "VERSION: 0.1\r\n";
214     }
215     else ret = LSCP_FAILED;
216 capela 105 }
217     else ret = LSCP_FAILED;
218     }
219 capela 125 else if (lscp_parser_test(&tok, "LIST")) {
220     if (lscp_parser_test(&tok, "CHANNELS")) {
221     // Getting all created sampler channel list.
222     // GET CHANNELS
223     if (iChannel > 0) {
224     strcpy(szTemp, "0");
225     for (i = 1; i < iChannel; i++)
226     sprintf(szTemp + strlen(szTemp), ",%d", i);
227     strcat(szTemp, "\r\n");
228     pszResult = szTemp;
229     }
230     else ret = LSCP_FAILED;
231     }
232     else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICES")) {
233     // Getting all created audio output device list.
234     // GET AUDIO_OUTPUT_DEVICES
235     pszResult = "0,1\r\n";
236     }
237     else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICES")) {
238     // Getting all created MID input device list.
239     // GET MIDI_INPUT_DEVICES
240     pszResult = "0\r\n";
241     }
242     else ret = LSCP_FAILED;
243     }
244 capela 105 else if (lscp_parser_test(&tok, "SET")) {
245     if (lscp_parser_test(&tok, "CHANNEL")) {
246     if (lscp_parser_test(&tok, "VOLUME")) {
247     // Setting channel volume:
248     // SET CHANNEL VOLUME <sampler-channel> <volume>
249     }
250     else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_TYPE")) {
251     // Setting audio output type:
252     // SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
253     }
254 capela 125 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) {
255     // Setting audio output device:
256     // SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
257     }
258 capela 105 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_CHANNEL")) {
259     // Setting audio output channel:
260 capela 125 // SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-in> <audio-out>
261 capela 105 }
262     else if (lscp_parser_test(&tok, "MIDI_INPUT_TYPE")) {
263     // Setting MIDI input type:
264     // SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
265     }
266 capela 125 else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) {
267     // Setting MIDI input device:
268     // SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
269     }
270 capela 105 else if (lscp_parser_test(&tok, "MIDI_INPUT_PORT")) {
271     // Setting MIDI input port:
272     // SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
273     }
274     else if (lscp_parser_test(&tok, "MIDI_INPUT_CHANNEL")) {
275     // Setting MIDI input channel:
276     // SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
277     }
278     else ret = LSCP_FAILED;
279     }
280     else ret = LSCP_FAILED;
281     }
282     else if (lscp_parser_test(&tok, "LOAD")) {
283     if (lscp_parser_test(&tok, "ENGINE")) {
284     // Loading a sampler engine:
285     // LOAD ENGINE <engine-name> <sampler-channel>
286     }
287     else if (lscp_parser_test(&tok, "INSTRUMENT")) {
288     // Loading an instrument:
289 capela 144 // LOAD INSTRUMENT [NON_MODAL] <filename> <instr-index> <sampler-channel>
290 capela 105 }
291     else ret = LSCP_FAILED;
292     }
293     else if (lscp_parser_test2(&tok, "ADD", "CHANNEL")) {
294     // Adding a new sampler channel:
295     // ADD CHANNEL
296     sprintf(szTemp, "OK[%d]", iChannel++);
297     pszResult = szTemp;
298     }
299     else if (lscp_parser_test2(&tok, "REMOVE", "CHANNEL")) {
300     // Removing a sampler channel:
301     // REMOVE CHANNEL <sampler-channel>
302     }
303     else if (lscp_parser_test2(&tok, "RESET", "CHANNEL")) {
304     // Resetting a sampler channel:
305     // RESET CHANNEL <sampler-channel>
306     }
307 capela 146 else if (lscp_parser_test(&tok, "SUBSCRIBE")) {
308     // Register frontend for receiving event notification messages:
309     // SUBSCRIBE <event>
310     ret = lscp_server_subscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok)));
311 capela 105 }
312 capela 146 else if (lscp_parser_test(&tok, "UNSUBSCRIBE")) {
313     // Deregister frontend for not receiving event notification messages anymore:
314     // UNSUBSCRIBE <event>
315     ret = lscp_server_unsubscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok)));
316 capela 105 }
317     else if (lscp_parser_test(&tok, "QUIT")) {
318     // Close client connection:
319     // QUIT
320     lscp_parser_free(&tok);
321     return LSCP_FAILED; // Disconnect.
322     }
323     else ret = LSCP_FAILED;
324    
325     lscp_parser_free(&tok);
326    
327     if (pszResult == NULL)
328     pszResult = (ret == LSCP_OK ? "OK\r\n" : "ERR:1:Failed\r\n");
329    
330     fprintf(stderr, "> %s", pszResult);
331    
332     return lscp_server_result(pConnect, pszResult, strlen(pszResult));
333     }
334    
335     ////////////////////////////////////////////////////////////////////////
336    
337     void server_usage (void)
338     {
339     printf("\n %s %s (Build: %s)\n", lscp_server_package(), lscp_server_version(), lscp_server_build());
340    
341     fputs("\n Available server commands: help, exit, quit, list", stdout);
342     fputs("\n (all else are broadcast verbatim to subscribers)\n\n", stdout);
343     }
344    
345     void server_prompt (void)
346     {
347     fputs("lscp_server> ", stdout);
348     }
349    
350     int main (int argc, char *argv[] )
351     {
352     lscp_server_t *pServer;
353     char szLine[200];
354     int cchLine;
355     lscp_connect_t *p;
356    
357     #if defined(WIN32)
358     if (WSAStartup(MAKEWORD(1, 1), &_wsaData) != 0) {
359     fprintf(stderr, "lscp_server: WSAStartup failed.\n");
360     return -1;
361     }
362     #endif
363    
364     srand(time(NULL));
365    
366     pServer = lscp_server_create(SERVER_PORT, server_callback, NULL);
367     if (pServer == NULL)
368     return -1;
369    
370     server_usage();
371     server_prompt();
372    
373     while (fgets(szLine, sizeof(szLine), stdin)) {
374    
375     cchLine = strlen(szLine);
376     while (cchLine > 0 && (szLine[cchLine - 1] == '\n' || szLine[cchLine - 1] == '\r'))
377     cchLine--;
378     szLine[cchLine] = '\0';
379    
380     if (strcmp(szLine, "exit") == 0 || strcmp(szLine, "quit") == 0)
381     break;
382     else
383     if (strcmp(szLine, "list") == 0) {
384     for (p = pServer->connects.first; p; p = p->next) {
385 capela 146 printf("client: sock=%d addr=%s port=%d events=0x%04x.\n",
386 capela 105 p->client.sock,
387     inet_ntoa(p->client.addr.sin_addr),
388     ntohs(p->client.addr.sin_port),
389 capela 146 (int) p->events
390 capela 105 );
391     }
392     }
393     else
394     if (cchLine > 0 && strcmp(szLine, "help") != 0)
395 capela 146 lscp_server_broadcast(pServer, LSCP_EVENT_MISCELLANEOUS, szLine, strlen(szLine));
396 capela 105 else
397     server_usage();
398    
399     server_prompt();
400     }
401    
402     lscp_server_destroy(pServer);
403    
404     #if defined(WIN32)
405     WSACleanup();
406     #endif
407    
408     return 0;
409     }
410    
411     // end of example_server.c

  ViewVC Help
Powered by ViewVC