/[svn]/linuxsampler/trunk/src/network/lscpserver.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/network/lscpserver.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 56 - (show annotations) (download)
Tue Apr 27 09:21:58 2004 UTC (15 years, 4 months ago) by schoenebeck
File size: 16244 byte(s)
updated copyright header for 2004

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 #include "lscpserver.h"
24
25 #include "../engines/gig/Engine.h"
26
27 LSCPServer::LSCPServer(Sampler* pSampler) : Thread(false, 0, -4) {
28 this->pSampler = pSampler;
29 }
30
31 int LSCPServer::Main() {
32 hSocket = socket(AF_INET, SOCK_STREAM, 0);
33 if (hSocket < 0) {
34 std::cerr << "LSCPServer: Could not create server socket." << std::endl;
35 //return -1;
36 exit(EXIT_FAILURE);
37 }
38
39 SocketAddress.sin_family = AF_INET;
40 SocketAddress.sin_port = htons(LSCP_PORT);
41 SocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
42
43 if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
44 std::cerr << "LSCPServer: Could not bind server socket." << std::endl;
45 close(hSocket);
46 //return -1;
47 exit(EXIT_FAILURE);
48 }
49
50 listen(hSocket, 1);
51 dmsg(1,("LSCPServer: Server running.\n")); // server running
52
53 // now wait for client connections and handle their requests
54 sockaddr_in client;
55 int length = sizeof(client);
56 while (true) {
57 hSession = accept(hSocket, (sockaddr*) &client, (socklen_t*) &length);
58 if (hSession < 0) {
59 std::cerr << "LSCPServer: Client connection failed." << std::endl;
60 close(hSocket);
61 //return -1;
62 exit(EXIT_FAILURE);
63 }
64
65 dmsg(1,("LSCPServer: Client connection established.\n"));
66 //send(hSession, "Welcome!\r\n", 10, 0);
67
68 // Parser invocation
69 yyparse_param_t yyparse_param;
70 yyparse_param.pServer = this;
71 yylex_init(&yyparse_param.pScanner);
72 while (yyparse(&yyparse_param) == LSCP_SYNTAX_ERROR); // recall parser in case of syntax error
73 yylex_destroy(yyparse_param.pScanner);
74
75 close(hSession);
76 dmsg(1,("LSCPServer: Client connection terminated.\n"));
77 }
78 }
79
80 /**
81 * Will be called by the parser whenever it wants to send an answer to the
82 * client / frontend.
83 *
84 * @param ReturnMessage - message that will be send to the client
85 */
86 void LSCPServer::AnswerClient(String ReturnMessage) {
87 dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));
88 send(hSession, ReturnMessage.c_str(), ReturnMessage.size(), 0);
89 }
90
91 /**
92 * Will be called by the parser to load an instrument.
93 */
94 String LSCPServer::LoadInstrument(String Filename, uint uiInstrument, uint uiSamplerChannel) {
95 dmsg(2,("LSCPServer: LoadInstrument(Filename=%s,Instrument=%d,SamplerChannel=%d)\n", Filename.c_str(), uiInstrument, uiSamplerChannel));
96 result_t result;
97 try {
98 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
99 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
100 Engine* pEngine = pSamplerChannel->GetEngine();
101 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
102 pEngine->LoadInstrument(Filename.c_str(), uiInstrument);
103 result.type = result_type_success;
104 }
105 catch (LinuxSamplerException e) {
106 e.PrintMessage();
107 result.type = result_type_error;
108 result.code = LSCP_ERR_UNKNOWN;
109 result.message = e.Message();
110 }
111 return ConvertResult(result);
112 }
113
114 /**
115 * Will be called by the parser to load and deploy an engine.
116 */
117 String LSCPServer::LoadEngine(String EngineName, uint uiSamplerChannel) {
118 dmsg(2,("LSCPServer: LoadEngine(EngineName=%s,SamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));
119 result_t result;
120 try {
121 engine_type_t type;
122 if (EngineName == "gig") type = engine_type_gig;
123 else throw LinuxSamplerException("Unknown engine type");
124 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
125 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
126 pSamplerChannel->LoadEngine(type);
127 result.type = result_type_success;
128 }
129 catch (LinuxSamplerException e) {
130 e.PrintMessage();
131 result.type = result_type_error;
132 result.code = LSCP_ERR_UNKNOWN;
133 result.message = e.Message();
134 }
135 return ConvertResult(result);
136 }
137
138 /**
139 * Will be called by the parser to get the amount of sampler channels.
140 */
141 String LSCPServer::GetChannels() {
142 dmsg(2,("LSCPServer: GetChannels()\n"));
143 return ToString(pSampler->SamplerChannels()) + "\r\n";
144 }
145
146 /**
147 * Will be called by the parser to add a sampler channel.
148 */
149 String LSCPServer::AddChannel() {
150 dmsg(2,("LSCPServer: AddChannel()\n"));
151 SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
152 return "OK[" + ToString(pSamplerChannel->Index()) + "]\r\n";
153 }
154
155 /**
156 * Will be called by the parser to remove a sampler channel.
157 */
158 String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
159 dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
160 pSampler->RemoveSamplerChannel(uiSamplerChannel);
161 return "OK\r\n";
162 }
163
164 /**
165 * Will be called by the parser to get all available engines.
166 */
167 String LSCPServer::GetAvailableEngines() {
168 dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
169 return "gig\r\n";
170 }
171
172 /**
173 * Will be called by the parser to get descriptions for a particular engine.
174 */
175 String LSCPServer::GetEngineInfo(String EngineName) {
176 dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
177 result_t result;
178 try {
179 if (EngineName == "gig") {
180 Engine* pEngine = new LinuxSampler::gig::Engine;
181 String info = pEngine->Description() + "\r\n";
182 delete pEngine;
183 return info; // success
184 }
185 else throw LinuxSamplerException("Unknown engine type");
186 }
187 catch (LinuxSamplerException e) {
188 e.PrintMessage();
189 result.type = result_type_error;
190 result.code = LSCP_ERR_UNKNOWN;
191 result.message = e.Message();
192 }
193 return ConvertResult(result);
194 }
195
196 /**
197 * Will be called by the parser to get informations about a particular
198 * sampler channel.
199 */
200 String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
201 dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
202 return "ERR:0:Not implemented yet.\r\n";
203 }
204
205 /**
206 * Will be called by the parser to get the amount of active voices on a
207 * particular sampler channel.
208 */
209 String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
210 dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
211 result_t result;
212 try {
213 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
214 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
215 Engine* pEngine = pSamplerChannel->GetEngine();
216 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
217 return ToString(pEngine->VoiceCount()) + "\r\n"; // success
218 }
219 catch (LinuxSamplerException e) {
220 e.PrintMessage();
221 result.type = result_type_error;
222 result.code = LSCP_ERR_UNKNOWN;
223 result.message = e.Message();
224 }
225 return ConvertResult(result);
226 }
227
228 /**
229 * Will be called by the parser to get the amount of active disk streams on a
230 * particular sampler channel.
231 */
232 String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
233 dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
234 result_t result;
235 try {
236 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
237 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
238 Engine* pEngine = pSamplerChannel->GetEngine();
239 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
240 return ToString(pEngine->DiskStreamCount()) + "\r\n"; // success
241 }
242 catch (LinuxSamplerException e) {
243 e.PrintMessage();
244 result.type = result_type_error;
245 result.code = LSCP_ERR_UNKNOWN;
246 result.message = e.Message();
247 }
248 return ConvertResult(result);
249 }
250
251 /**
252 * Will be called by the parser to get the buffer fill states of all disk
253 * streams on a particular sampler channel.
254 */
255 String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
256 dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
257 result_t result;
258 try {
259 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
260 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
261 Engine* pEngine = pSamplerChannel->GetEngine();
262 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
263 if (!pEngine->DiskStreamSupported()) return "NA\r\n";
264 switch (ResponseType) {
265 case fill_response_bytes:
266 return ToString(pEngine->DiskStreamBufferFillBytes()) + "\r\n"; // success
267 case fill_response_percentage:
268 return ToString(pEngine->DiskStreamBufferFillPercentage()) + "\r\n"; // success
269 default:
270 throw LinuxSamplerException("Unknown fill response type");
271 }
272 }
273 catch (LinuxSamplerException e) {
274 e.PrintMessage();
275 result.type = result_type_error;
276 result.code = LSCP_ERR_UNKNOWN;
277 result.message = e.Message();
278 }
279 return ConvertResult(result);
280 }
281
282 /**
283 * Will be called by the parser to change the audio output type on a
284 * particular sampler channel.
285 */
286 String LSCPServer::SetAudioOutputType(audio_output_type_t AudioOutputType, uint uiSamplerChannel) {
287 dmsg(2,("LSCPServer: SetAudioOutputType(AudioOutputType=%d, SamplerChannel=%d)\n", AudioOutputType, uiSamplerChannel));
288 result_t result;
289 try {
290 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
291 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
292 pSamplerChannel->SetAudioOutputDevice(AudioOutputType);
293 result.type = result_type_success;
294 }
295 catch (LinuxSamplerException e) {
296 e.PrintMessage();
297 result.type = result_type_error;
298 result.code = LSCP_ERR_UNKNOWN;
299 result.message = e.Message();
300 }
301 return ConvertResult(result);
302 }
303
304 /**
305 * Will be called by the parser to change the audio output channel for
306 * playback on a particular sampler channel.
307 */
308 String LSCPServer::SetAudioOutputChannel(uint AudioOutputChannel, uint uiSamplerChannel) {
309 dmsg(2,("LSCPServer: SetAudioOutputChannel(AudioOutputChannel=%d, SamplerChannel=%d)\n", AudioOutputChannel, uiSamplerChannel));
310 return "ERR:0:Not implemented yet.\r\n";
311 }
312
313 String LSCPServer::SetMIDIInputType(midi_input_type_t MidiInputType, uint uiSamplerChannel) {
314 dmsg(2,("LSCPServer: SetMIDIInputType(MidiInputType=%d, SamplerChannel=%d)\n", MidiInputType, uiSamplerChannel));
315 result_t result;
316 try {
317 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
318 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
319 pSamplerChannel->SetMidiInputDevice(MidiInputType);
320 result.type = result_type_success;
321 }
322 catch (LinuxSamplerException e) {
323 e.PrintMessage();
324 result.type = result_type_error;
325 result.code = LSCP_ERR_UNKNOWN;
326 result.message = e.Message();
327 }
328 return ConvertResult(result);
329 }
330
331 /**
332 * Will be called by the parser to change the MIDI input port on which the
333 * engine of a particular sampler channel should listen to.
334 */
335 String LSCPServer::SetMIDIInputPort(String MIDIInputPort, uint uiSamplerchannel) {
336 dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIInputPort=%s, Samplerchannel=%d)\n", MIDIInputPort.c_str(), uiSamplerchannel));
337 return "ERR:0:Not implemented yet.\r\n";
338 }
339
340 /**
341 * Will be called by the parser to change the MIDI input channel on which the
342 * engine of a particular sampler channel should listen to.
343 */
344 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
345 dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n", MIDIChannel, uiSamplerChannel));
346 return "ERR:0:Not implemented yet.\r\n";
347 }
348
349 /**
350 * Will be called by the parser to change the global volume factor on a
351 * particular sampler channel.
352 */
353 String LSCPServer::SetVolume(double Volume, uint uiSamplerChannel) {
354 dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", Volume, uiSamplerChannel));
355 result_t result;
356 try {
357 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
358 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
359 Engine* pEngine = pSamplerChannel->GetEngine();
360 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
361 pEngine->Volume(Volume);
362 result.type = result_type_success;
363 }
364 catch (LinuxSamplerException e) {
365 e.PrintMessage();
366 result.type = result_type_error;
367 result.code = LSCP_ERR_UNKNOWN;
368 result.message = e.Message();
369 }
370 return ConvertResult(result);
371 }
372
373 /**
374 * Will be called by the parser to reset a particular sampler channel.
375 */
376 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
377 dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
378 result_t result;
379 try {
380 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
381 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
382 Engine* pEngine = pSamplerChannel->GetEngine();
383 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
384 pEngine->Reset();
385 result.type = result_type_success;
386 }
387 catch (LinuxSamplerException e) {
388 e.PrintMessage();
389 result.type = result_type_error;
390 result.code = LSCP_ERR_UNKNOWN;
391 result.message = e.Message();
392 }
393 return ConvertResult(result);
394 }
395
396 /**
397 * Will be called by the parser to subscribe a client (frontend) on the
398 * server for receiving event messages.
399 */
400 String LSCPServer::SubscribeNotification(uint UDPPort) {
401 dmsg(2,("LSCPServer: SubscribeNotification(UDPPort=%d)\n", UDPPort));
402 return "ERR:0:Not implemented yet.\r\n";
403 }
404
405 /**
406 * Will be called by the parser to unsubscribe a client on the server
407 * for not receiving further event messages.
408 */
409 String LSCPServer::UnsubscribeNotification(String SessionID) {
410 dmsg(2,("LSCPServer: UnsubscribeNotification(SessionID=%s)\n", SessionID.c_str()));
411 return "ERR:0:Not implemented yet.\r\n";
412 }

  ViewVC Help
Powered by ViewVC