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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 117 - (hide annotations) (download)
Tue Jun 8 01:29:08 2004 UTC (19 years, 9 months ago) by senkov
File size: 19218 byte(s)
Updated GET CHANNEL INFO to send uninitialized params with "NONE"/0

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

  ViewVC Help
Powered by ViewVC