/[svn]/linuxsampler/trunk/src/network/lscp.y
ViewVC logotype

Contents of /linuxsampler/trunk/src/network/lscp.y

Parent Directory Parent Directory | Revision Log Revision Log


Revision 143 - (show annotations) (download)
Wed Jun 23 18:54:08 2004 UTC (19 years, 9 months ago) by capela
File size: 14880 byte(s)
* SET CHANNEL AUDIO_OUTPUT_TYPE <chan> <driver> command is back!
  creates an audio output device instance of the given driver type
  ('Jack' or 'Alsa') with default parameters if none exists,
  otherwise it just picks the first available device and assign
  it to the intended sampler channel.

* The AudioOutputDevice class get's a new pure virtual method,
  Driver(), which is implemented on both of the existing inherited
  classes, AudioOutputDeviceAlsa and AudioOutputDeviceJack, with
  the sole purpose to return the driver type name as a String
  ('Alsa' and 'Jack', respectively).

* The quoting on the filename argument for the LOAD INSTRUMENT
  command has been made optional; you can have both ways, with
  single quotes or none, keeping compability with older LSCP
  specification.

* An additional sanity check is made on LOAD INSTRUMENT, whether
  the sampler channel has an audio output device assigned, thus
  preventing the server from crashing on instrument file load.

* The GET AUDIO_OUTPUT_DEVICE INFO now includes the missing
  'driver' item, as predicted by the draft protocol document.

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (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 *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 %{
24
25 #include "lscpparser.h"
26 #include "lscpserver.h"
27
28 // as we need an reentrant scanner, we have to pass the pointer to the scanner with each yylex() call
29 #define YYLEX_PARAM ((yyparse_param_t*) yyparse_param)->pScanner
30
31 // to save us typing work in the rules action definitions
32 #define LSCPSERVER ((yyparse_param_t*) yyparse_param)->pServer
33
34 // clears input buffer and restarts scanner.
35 void restart(yyparse_param_t* pparam, int& yychar);
36 #define RESTART restart((yyparse_param_t*) YYPARSE_PARAM, yychar)
37
38 // external reference to the main scanner function yylex()
39 extern YY_DECL;
40
41 // external reference to restart the lex scanner
42 extern void yyrestart(FILE* input_file, yyscan_t yyscanner);
43
44 // we provide our own version of yyerror() so we don't have to link against the yacc library
45 void yyerror(const char* s);
46
47 %}
48
49 // reentrant parser
50 %pure_parser
51
52 %token <Char> CHAR
53 %token <Dotnum> DOTNUM
54 %token <Number> NUMBER
55 %token <String> STRINGVAL
56 %token SP LF CR HASH EQ
57 %token ADD GET CREATE DESTROY LIST LOAD NON_MODAL REMOVE SET SUBSCRIBE UNSUBSCRIBE RESET QUIT
58 %token CHANNEL NOTIFICATION
59 %token AVAILABLE_ENGINES AVAILABLE_AUDIO_OUTPUT_DRIVERS CHANNELS INFO BUFFER_FILL STREAM_COUNT VOICE_COUNT
60 %token INSTRUMENT ENGINE
61 %token AUDIO_OUTPUT_CHANNEL AUDIO_OUTPUT_CHANNEL_PARAMETER AUDIO_OUTPUT_DEVICE AUDIO_OUTPUT_DEVICES AUDIO_OUTPUT_DEVICE_PARAMETER AUDIO_OUTPUT_DRIVER AUDIO_OUTPUT_DRIVER_PARAMETER AUDIO_OUTPUT_TYPE MIDI_INPUT_PORT MIDI_INPUT_CHANNEL MIDI_INPUT_TYPE VOLUME
62 %token BYTES PERCENTAGE
63 %token MISCELLANEOUS
64
65 %type <Dotnum> volume
66 %type <Number> sampler_channel instrument_index audio_output_channel midi_input_channel
67 %type <String> string param_val filename engine_name midi_input_port command create_instruction destroy_instruction get_instruction list_instruction load_instruction set_chan_instruction load_instr_args load_engine_args audio_output_type midi_input_type set_instruction subscribe_event unsubscribe_event
68 %type <FillResponse> buffer_size_type
69 %type <KeyValList> key_val_list
70
71 %start input
72
73 %%
74
75 //TODO: return more meaningful error messages
76
77 input : line
78 | input LF line
79 | input CR LF line
80 ;
81
82 line : /* epsilon (empty line ignored) */
83 | comment
84 | command { LSCPSERVER->AnswerClient($1); }
85 | error { LSCPSERVER->AnswerClient("Err:0:Unknown command.\r\n"); RESTART; return LSCP_SYNTAX_ERROR; }
86 ;
87
88 comment : HASH
89 | comment HASH
90 | comment SP
91 | comment NUMBER
92 | comment string
93 ;
94
95 command : ADD SP CHANNEL { $$ = LSCPSERVER->AddChannel(); }
96 | GET SP get_instruction { $$ = $3; }
97 | CREATE SP create_instruction { $$ = $3; }
98 | DESTROY SP destroy_instruction { $$ = $3; }
99 | LIST SP list_instruction { $$ = $3; }
100 | LOAD SP load_instruction { $$ = $3; }
101 | REMOVE SP CHANNEL SP sampler_channel { $$ = LSCPSERVER->RemoveChannel($5); }
102 | SET SP set_instruction { $$ = $3; }
103 | SUBSCRIBE SP subscribe_event { $$ = $3; }
104 | UNSUBSCRIBE SP unsubscribe_event { $$ = $3; }
105 | RESET SP CHANNEL SP sampler_channel { $$ = LSCPSERVER->ResetChannel($5); }
106 | QUIT { LSCPSERVER->AnswerClient("Bye!\r\n"); return 0; }
107 ;
108
109 subscribe_event : CHANNELS { $$ = LSCPSERVER->SubscribeNotification(event_channels); }
110 | VOICE_COUNT { $$ = LSCPSERVER->SubscribeNotification(event_voice_count); }
111 | STREAM_COUNT { $$ = LSCPSERVER->SubscribeNotification(event_stream_count); }
112 | BUFFER_FILL { $$ = LSCPSERVER->SubscribeNotification(event_channel_buffer_fill); }
113 | INFO { $$ = LSCPSERVER->SubscribeNotification(event_channel_info); }
114 | MISCELLANEOUS { $$ = LSCPSERVER->SubscribeNotification(event_misc); }
115 ;
116
117 unsubscribe_event : CHANNELS { $$ = LSCPSERVER->UnsubscribeNotification(event_channels); }
118 | VOICE_COUNT { $$ = LSCPSERVER->UnsubscribeNotification(event_voice_count); }
119 | STREAM_COUNT { $$ = LSCPSERVER->UnsubscribeNotification(event_stream_count); }
120 | BUFFER_FILL { $$ = LSCPSERVER->UnsubscribeNotification(event_channel_buffer_fill); }
121 | INFO { $$ = LSCPSERVER->UnsubscribeNotification(event_channel_info); }
122 | MISCELLANEOUS { $$ = LSCPSERVER->UnsubscribeNotification(event_misc); }
123 ;
124
125 get_instruction : AVAILABLE_ENGINES { $$ = LSCPSERVER->GetAvailableEngines(); }
126 | AVAILABLE_AUDIO_OUTPUT_DRIVERS { $$ = LSCPSERVER->GetAvailableAudioOutputDrivers(); }
127 | AUDIO_OUTPUT_DRIVER SP INFO SP string { $$ = LSCPSERVER->GetAudioOutputDriverInfo($5); }
128 | AUDIO_OUTPUT_DRIVER_PARAMETER SP INFO SP string SP string { $$ = LSCPSERVER->GetAudioOutputDriverParameterInfo($5, $7); }
129 | AUDIO_OUTPUT_DRIVER_PARAMETER SP INFO SP string SP string SP key_val_list { $$ = LSCPSERVER->GetAudioOutputDriverParameterInfo($5, $7, $9); }
130 | AUDIO_OUTPUT_DEVICES { $$ = LSCPSERVER->GetAudioOutputDeviceCount(); }
131 | AUDIO_OUTPUT_DEVICE SP INFO SP NUMBER { $$ = LSCPSERVER->GetAudioOutputDeviceInfo($5); }
132 | AUDIO_OUTPUT_CHANNEL SP INFO SP NUMBER SP NUMBER { $$ = LSCPSERVER->GetAudioOutputChannelInfo($5, $7); }
133 | AUDIO_OUTPUT_CHANNEL_PARAMETER SP INFO SP NUMBER SP NUMBER SP string { $$ = LSCPSERVER->GetAudioOutputChannelParameterInfo($5, $7, $9); }
134 | CHANNELS { $$ = LSCPSERVER->GetChannels(); }
135 | CHANNEL SP INFO SP sampler_channel { $$ = LSCPSERVER->GetChannelInfo($5); }
136 | CHANNEL SP BUFFER_FILL SP buffer_size_type SP sampler_channel { $$ = LSCPSERVER->GetBufferFill($5, $7); }
137 | CHANNEL SP STREAM_COUNT SP sampler_channel { $$ = LSCPSERVER->GetStreamCount($5); }
138 | CHANNEL SP VOICE_COUNT SP sampler_channel { $$ = LSCPSERVER->GetVoiceCount($5); }
139 | ENGINE SP INFO SP engine_name { $$ = LSCPSERVER->GetEngineInfo($5); }
140 ;
141
142 set_instruction : AUDIO_OUTPUT_DEVICE_PARAMETER SP NUMBER SP string EQ param_val { $$ = LSCPSERVER->SetAudioOutputDeviceParameter($3, $5, $7); }
143 | AUDIO_OUTPUT_CHANNEL_PARAMETER SP NUMBER SP NUMBER SP string EQ param_val { $$ = LSCPSERVER->SetAudioOutputChannelParameter($3, $5, $7, $9); }
144 | CHANNEL SP set_chan_instruction { $$ = $3; }
145 ;
146
147 create_instruction : AUDIO_OUTPUT_DEVICE SP string SP key_val_list { $$ = LSCPSERVER->CreateAudioOutputDevice($3,$5); }
148 | AUDIO_OUTPUT_DEVICE SP string { $$ = LSCPSERVER->CreateAudioOutputDevice($3); }
149 ;
150
151 destroy_instruction : AUDIO_OUTPUT_DEVICE SP NUMBER { $$ = LSCPSERVER->DestroyAudioOutputDevice($3); }
152 ;
153
154 load_instruction : INSTRUMENT SP load_instr_args { $$ = $3; }
155 | ENGINE SP load_engine_args { $$ = $3; }
156 ;
157
158 set_chan_instruction : AUDIO_OUTPUT_DEVICE SP sampler_channel SP NUMBER { $$ = LSCPSERVER->SetAudioOutputDevice($5, $3); }
159 | AUDIO_OUTPUT_CHANNEL SP sampler_channel SP audio_output_channel SP audio_output_channel { $$ = LSCPSERVER->SetAudioOutputChannel($5, $7, $3); }
160 | AUDIO_OUTPUT_TYPE SP sampler_channel SP audio_output_type { $$ = LSCPSERVER->SetAudioOutputType($5, $3); }
161 | MIDI_INPUT_PORT SP sampler_channel SP midi_input_port { $$ = LSCPSERVER->SetMIDIInputPort($5, $3); }
162 | MIDI_INPUT_CHANNEL SP sampler_channel SP midi_input_channel { $$ = LSCPSERVER->SetMIDIInputChannel($5, $3); }
163 | MIDI_INPUT_TYPE SP sampler_channel SP midi_input_type { $$ = LSCPSERVER->SetMIDIInputType($5, $3); }
164 | VOLUME SP sampler_channel SP volume { $$ = LSCPSERVER->SetVolume($5, $3); }
165 ;
166
167 key_val_list : string EQ param_val { $$[$1] = $3; }
168 | key_val_list SP string EQ param_val { $$ = $1; $$[$3] = $5; }
169 ;
170
171 buffer_size_type : BYTES { $$ = fill_response_bytes; }
172 | PERCENTAGE { $$ = fill_response_percentage; }
173 ;
174
175 list_instruction : AUDIO_OUTPUT_DEVICES { $$ = LSCPSERVER->GetAudioOutputDevices(); }
176 ;
177
178 load_instr_args : filename SP instrument_index SP sampler_channel { $$ = LSCPSERVER->LoadInstrument($1, $3, $5); }
179 | NON_MODAL SP filename SP instrument_index SP sampler_channel { $$ = LSCPSERVER->LoadInstrument($3, $5, $7, true); }
180 ;
181
182 load_engine_args : engine_name SP sampler_channel { $$ = LSCPSERVER->LoadEngine($1, $3); }
183 ;
184
185 audio_output_type : string
186 ;
187
188 midi_input_type : string
189 ;
190
191 volume : DOTNUM
192 | NUMBER { $$ = $1; }
193 ;
194
195 sampler_channel : NUMBER
196 ;
197
198 instrument_index : NUMBER
199 ;
200
201 audio_output_channel : NUMBER
202 ;
203
204 midi_input_channel : NUMBER
205 ;
206
207 engine_name : string
208 ;
209
210 midi_input_port : STRINGVAL
211 ;
212
213 filename : STRINGVAL
214 | string
215 ;
216
217 param_val : STRINGVAL { $$ = $1; }
218 | NUMBER { std::stringstream ss; ss << $1; $$ = ss.str(); }
219 | DOTNUM { std::stringstream ss; ss << $1; $$ = ss.str(); }
220 ;
221
222 string : CHAR { std::string s; s = $1; $$ = s; }
223 | string CHAR { $$ = $1 + $2; }
224 ;
225
226 %%
227
228 /**
229 * Will be called when an error occured (usually syntax error).
230 */
231 void yyerror(const char* s) {
232 dmsg(2,("LSCPParser: %s\n", s));
233 }
234
235 /**
236 * Clears input buffer and restarts scanner.
237 */
238 void restart(yyparse_param_t* pparam, int& yychar) {
239 // restart scanner
240 yyrestart(stdin, pparam->pScanner);
241 // flush input buffer
242 static char buf[1024];
243 while(recv(hSession, buf, 1024, MSG_DONTWAIT) > 0);
244 // reset lookahead symbol
245 yyclearin;
246 }

  ViewVC Help
Powered by ViewVC