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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 360 - (hide annotations) (download)
Mon Feb 7 00:19:30 2005 UTC (19 years, 2 months ago) by senkov
File size: 9290 byte(s)
* Updated implementation for real time notify messages:
VOICE_COUNT, STREAM_COUNT, BUFFER_FILL

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

  ViewVC Help
Powered by ViewVC