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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 411 - (hide annotations) (download)
Sat Feb 26 02:01:14 2005 UTC (19 years, 1 month ago) by schoenebeck
File size: 9711 byte(s)
* design change: using now one sampler engine instance and one disk thread
  instance for all sampler channels that are connected to the same audio
  output device (and are using the same engine type of course)
* added EngineFactory / EngineChannelFactory to remove the annoying build
  dependencies e.g. of the lscpserver to the actual sampler engine
  implementations
* bumped version to 0.3.0 (current CVS state is still quite broken,
  previous, stable CVS version was tagged as "v0_2_0" and is also available
  as source tarball)

1 schoenebeck 9 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 61 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 411 * Copyright (C) 2005 Christian Schoenebeck *
7 schoenebeck 9 * *
8     * This program is free software; you can redistribute it and/or modify *
9     * it under the terms of the GNU General Public License as published by *
10     * the Free Software Foundation; either version 2 of the License, or *
11     * (at your option) any later version. *
12     * *
13     * This program is distributed in the hope that it will be useful, *
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16     * GNU General Public License for more details. *
17     * *
18     * You should have received a copy of the GNU General Public License *
19     * along with this program; if not, write to the Free Software *
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23    
24     #include <getopt.h>
25     #include <signal.h>
26    
27 schoenebeck 53 #include "Sampler.h"
28 schoenebeck 207 #include "drivers/midi/MidiInputDeviceFactory.h"
29 schoenebeck 203 #include "drivers/audio/AudioOutputDeviceFactory.h"
30 senkov 325 #include "engines/gig/Profiler.h"
31 schoenebeck 35 #include "network/lscpserver.h"
32 schoenebeck 271 #include "common/stacktrace.h"
33 schoenebeck 319 #include "common/Features.h"
34 schoenebeck 9
35 schoenebeck 53 using namespace LinuxSampler;
36    
37 schoenebeck 211 Sampler* pSampler = NULL;
38     LSCPServer* pLSCPServer = NULL;
39 schoenebeck 271 pthread_t main_thread;
40 senkov 325 bool profile = false;
41     bool tune = true;
42 schoenebeck 9
43     void parse_options(int argc, char **argv);
44     void signal_handler(int signal);
45 schoenebeck 271 void kill_app();
46 schoenebeck 9
47     int main(int argc, char **argv) {
48    
49 schoenebeck 271 // initialize the stack trace mechanism with our binary file
50     StackTraceInit(argv[0], -1);
51    
52     main_thread = pthread_self();
53    
54 schoenebeck 9 // setting signal handler for catching SIGINT (thus e.g. <CTRL><C>)
55     signal(SIGINT, signal_handler);
56    
57 schoenebeck 271 // register signal handler for all unusual signals
58     // (we will print the stack trace and exit)
59     struct sigaction sact;
60     sigemptyset(&sact.sa_mask);
61     sact.sa_flags = 0;
62     sact.sa_handler = signal_handler;
63     sigaction(SIGSEGV, &sact, NULL);
64     sigaction(SIGBUS, &sact, NULL);
65     sigaction(SIGILL, &sact, NULL);
66     sigaction(SIGFPE, &sact, NULL);
67     sigaction(SIGUSR1, &sact, NULL);
68     sigaction(SIGUSR2, &sact, NULL);
69    
70 schoenebeck 9 // parse and assign command line options
71 senkov 325 parse_options(argc, argv);
72 schoenebeck 9
73 schoenebeck 207 dmsg(1,("LinuxSampler %s\n", VERSION));
74     dmsg(1,("Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck\n"));
75 schoenebeck 411 dmsg(1,("Copyright (C) 2005 Christian Schoenebeck\n"));
76 schoenebeck 123
77 senkov 325 if (tune)
78     {
79     // detect and print system / CPU specific features
80     String sFeatures;
81     Features::detect();
82     #if ARCH_X86
83     if (Features::supportsMMX()) sFeatures += " MMX";
84     if (Features::supportsSSE()) sFeatures += " SSE";
85     #endif // ARCH_X86
86     if (!sFeatures.size()) sFeatures = " None";
87     dmsg(1,("Detected features:%s\n",sFeatures.c_str()));
88     }
89 schoenebeck 319
90 schoenebeck 53 // create LinuxSampler instance
91 schoenebeck 123 dmsg(1,("Creating Sampler..."));
92 schoenebeck 53 pSampler = new Sampler;
93 schoenebeck 123 dmsg(1,("OK\n"));
94 schoenebeck 53
95 schoenebeck 207 dmsg(1,("Registered MIDI input drivers: %s\n", MidiInputDeviceFactory::AvailableDriversAsString().c_str()));
96 schoenebeck 123 dmsg(1,("Registered audio output drivers: %s\n", AudioOutputDeviceFactory::AvailableDriversAsString().c_str()));
97    
98 schoenebeck 53 // start LSCP network server
99 schoenebeck 214 dmsg(1,("Starting LSCP network server (on TCP port %d)...", LSCP_PORT));
100 schoenebeck 53 pLSCPServer = new LSCPServer(pSampler);
101     pLSCPServer->StartThread();
102 schoenebeck 211 pLSCPServer->WaitUntilInitialized();
103 schoenebeck 12 dmsg(1,("OK\n"));
104 schoenebeck 9
105 senkov 325 if (profile)
106     {
107     dmsg(1,("Calibrating profiler..."));
108     gig::Profiler::Calibrate();
109     gig::Profiler::Reset();
110     dmsg(1,("OK\n"));
111     }
112    
113 schoenebeck 9 printf("LinuxSampler initialization completed.\n");
114    
115 senkov 360 std::list<LSCPEvent::event_t> rtEvents;
116     rtEvents.push_back(LSCPEvent::event_voice_count);
117     rtEvents.push_back(LSCPEvent::event_stream_count);
118     rtEvents.push_back(LSCPEvent::event_buffer_fill);
119    
120     while(true)
121     {
122 schoenebeck 53 /*printf("Voices: %3.3d (Max: %3.3d) Streams: %3.3d (Max: %3.3d, Unused: %3.3d)\r",
123 schoenebeck 35 pEngine->ActiveVoiceCount, pEngine->ActiveVoiceCountMax,
124     pEngine->pDiskThread->ActiveStreamCount, pEngine->pDiskThread->ActiveStreamCountMax, Stream::GetUnusedStreams());
125 schoenebeck 53 fflush(stdout);*/
126 senkov 325 sleep(1);
127     if (profile)
128     {
129     unsigned int samplingFreq = 48000; //FIXME: hardcoded for now
130     unsigned int bv = gig::Profiler::GetBogoVoices(samplingFreq);
131     if (bv != 0)
132     {
133     printf(" BogoVoices: %i \r", bv);
134     fflush(stdout);
135     }
136     }
137 senkov 360
138     if (LSCPServer::EventSubscribers(rtEvents))
139     {
140     LSCPServer::LockRTNotify();
141     std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
142     std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
143     for (; iter != channels.end(); iter++) {
144     SamplerChannel* pSamplerChannel = iter->second;
145 schoenebeck 411 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
146     if (!pEngineChannel) continue;
147     Engine* pEngine = pEngineChannel->GetEngine();
148 senkov 360 if (!pEngine) continue;
149     LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_voice_count, iter->first, pEngine->VoiceCount()));
150     LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_stream_count, iter->first, pEngine->DiskStreamCount()));
151     LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_buffer_fill, iter->first, pEngine->DiskStreamBufferFillPercentage()));
152     }
153     LSCPServer::UnlockRTNotify();
154     }
155    
156 senoner 10 }
157    
158 schoenebeck 9 return EXIT_SUCCESS;
159     }
160    
161 schoenebeck 271 void signal_handler(int iSignal) {
162     switch (iSignal) {
163     case SIGINT: {
164     if (pthread_equal(pthread_self(), main_thread)) {
165     if (pLSCPServer) {
166     pLSCPServer->StopThread();
167     delete pLSCPServer;
168     }
169     if (pSampler) delete pSampler;
170     printf("LinuxSampler stopped due to SIGINT.\n");
171     exit(EXIT_SUCCESS);
172     }
173     return;
174 schoenebeck 53 }
175 schoenebeck 271 case SIGSEGV:
176     std::cerr << ">>> FATAL ERROR: Segmentation fault (SIGSEGV) occured! <<<\n" << std::flush;
177     break;
178     case SIGBUS:
179     std::cerr << ">>> FATAL ERROR: Access to undefined portion of a memory object (SIGBUS) occured! <<<\n" << std::flush;
180     break;
181     case SIGILL:
182     std::cerr << ">>> FATAL ERROR: Illegal instruction (SIGILL) occured! <<<\n" << std::flush;
183     break;
184     case SIGFPE:
185     std::cerr << ">>> FATAL ERROR: Erroneous arithmetic operation (SIGFPE) occured! <<<\n" << std::flush;
186     break;
187     case SIGUSR1:
188     std::cerr << ">>> User defined signal 1 (SIGUSR1) received <<<\n" << std::flush;
189     break;
190     case SIGUSR2:
191     std::cerr << ">>> User defined signal 2 (SIGUSR2) received <<<\n" << std::flush;
192     break;
193     default: { // this should never happen, as we register for the signals we want
194     std::cerr << ">>> FATAL ERROR: Unknown signal received! <<<\n" << std::flush;
195     break;
196     }
197 schoenebeck 9 }
198 schoenebeck 271 signal(iSignal, SIG_DFL); // Reinstall default handler to prevent race conditions
199     std::cerr << "Showing stack trace...\n" << std::flush;
200     StackTrace();
201     sleep(2);
202     std::cerr << "Killing LinuxSampler...\n" << std::flush;
203     kill_app(); // Use abort() if we want to generate a core dump.
204 schoenebeck 9 }
205    
206 schoenebeck 271 void kill_app() {
207     kill(main_thread, SIGKILL);
208     }
209    
210 senkov 325 void parse_options(int argc, char **argv) {
211 schoenebeck 9 int res;
212     int option_index = 0;
213     static struct option long_options[] =
214     {
215     {"help",0,0,0},
216 senkov 325 {"version",0,0,0},
217     {"profile",0,0,0},
218     {"no-tune",0,0,0},
219 schoenebeck 9 {0,0,0,0}
220     };
221    
222     while (true) {
223 schoenebeck 361 /*
224     Stephane Letz : letz@grame.fr
225     getopt_long_only does not exist on OSX : replaced by getopt_long for now.
226     */
227     res = getopt_long(argc, argv, "", long_options, &option_index);
228 schoenebeck 9 if(res == -1) break;
229     if (res == 0) {
230     switch(option_index) {
231 senkov 325 case 0: // --help
232     printf("usage: linuxsampler [OPTIONS]\n\n");
233     printf("--help prints this message\n");
234     printf("--version prints version information\n");
235     printf("--profile profile synthesis algorithms\n");
236     printf("--no-tune disable assembly optimization\n");
237     exit(EXIT_SUCCESS);
238 schoenebeck 9 break;
239 senkov 325 case 1: // --version
240 schoenebeck 328 printf("LinuxSampler %s\n", VERSION);
241     exit(EXIT_SUCCESS);
242 schoenebeck 9 break;
243 senkov 325 case 2: // --profile
244     profile = true;
245 schoenebeck 20 break;
246 senkov 325 case 3: // --no-tune
247     tune = false;
248 schoenebeck 9 break;
249     }
250     }
251     }
252 senkov 325 }

  ViewVC Help
Powered by ViewVC