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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 319 - (hide annotations) (download)
Mon Dec 13 00:46:42 2004 UTC (19 years, 3 months ago) by schoenebeck
File size: 11492 byte(s)
* introduced 'synthesis mode' to reduce the amount of code and conditionals
  for the current synthesis case in the main synthesis loop
* support for MMX and SSE(1) in the core synthesis algorithms (CPU feature
  detection at runtime, only x86 so far)

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 schoenebeck 35 #include "network/lscpserver.h"
30 schoenebeck 271 #include "common/stacktrace.h"
31 schoenebeck 319 #include "common/Features.h"
32 schoenebeck 9
33 schoenebeck 53 using namespace LinuxSampler;
34    
35 schoenebeck 211 Sampler* pSampler = NULL;
36     LSCPServer* pLSCPServer = NULL;
37 schoenebeck 271 pthread_t main_thread;
38 schoenebeck 9
39     void parse_options(int argc, char **argv);
40     void signal_handler(int signal);
41 schoenebeck 271 void kill_app();
42 schoenebeck 9
43     int main(int argc, char **argv) {
44    
45 schoenebeck 271 // initialize the stack trace mechanism with our binary file
46     StackTraceInit(argv[0], -1);
47    
48     main_thread = pthread_self();
49    
50 schoenebeck 9 // setting signal handler for catching SIGINT (thus e.g. <CTRL><C>)
51     signal(SIGINT, signal_handler);
52    
53 schoenebeck 271 // register signal handler for all unusual signals
54     // (we will print the stack trace and exit)
55     struct sigaction sact;
56     sigemptyset(&sact.sa_mask);
57     sact.sa_flags = 0;
58     sact.sa_handler = signal_handler;
59     sigaction(SIGSEGV, &sact, NULL);
60     sigaction(SIGBUS, &sact, NULL);
61     sigaction(SIGILL, &sact, NULL);
62     sigaction(SIGFPE, &sact, NULL);
63     sigaction(SIGUSR1, &sact, NULL);
64     sigaction(SIGUSR2, &sact, NULL);
65    
66 schoenebeck 9 // parse and assign command line options
67 schoenebeck 53 //parse_options(argc, argv);
68 schoenebeck 9
69 schoenebeck 207 dmsg(1,("LinuxSampler %s\n", VERSION));
70     dmsg(1,("Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck\n"));
71 schoenebeck 123
72 schoenebeck 319 // detect and print system / CPU specific features
73     String sFeatures;
74     Features::detect();
75     #if ARCH_X86
76     if (Features::supportsMMX()) sFeatures += " MMX";
77     if (Features::supportsSSE()) sFeatures += " SSE";
78     #endif // ARCH_X86
79     if (!sFeatures.size()) sFeatures = " None";
80     dmsg(1,("Detected features:%s\n",sFeatures.c_str()));
81    
82 schoenebeck 53 // create LinuxSampler instance
83 schoenebeck 123 dmsg(1,("Creating Sampler..."));
84 schoenebeck 53 pSampler = new Sampler;
85 schoenebeck 123 dmsg(1,("OK\n"));
86 schoenebeck 53
87 schoenebeck 207 dmsg(1,("Registered MIDI input drivers: %s\n", MidiInputDeviceFactory::AvailableDriversAsString().c_str()));
88 schoenebeck 123 dmsg(1,("Registered audio output drivers: %s\n", AudioOutputDeviceFactory::AvailableDriversAsString().c_str()));
89    
90 schoenebeck 53 // start LSCP network server
91 schoenebeck 214 dmsg(1,("Starting LSCP network server (on TCP port %d)...", LSCP_PORT));
92 schoenebeck 53 pLSCPServer = new LSCPServer(pSampler);
93     pLSCPServer->StartThread();
94 schoenebeck 211 pLSCPServer->WaitUntilInitialized();
95 schoenebeck 12 dmsg(1,("OK\n"));
96 schoenebeck 9
97     printf("LinuxSampler initialization completed.\n");
98    
99 senoner 10 while(true) {
100 schoenebeck 53 /*printf("Voices: %3.3d (Max: %3.3d) Streams: %3.3d (Max: %3.3d, Unused: %3.3d)\r",
101 schoenebeck 35 pEngine->ActiveVoiceCount, pEngine->ActiveVoiceCountMax,
102     pEngine->pDiskThread->ActiveStreamCount, pEngine->pDiskThread->ActiveStreamCountMax, Stream::GetUnusedStreams());
103 schoenebeck 53 fflush(stdout);*/
104 senoner 10 usleep(500000);
105     }
106    
107 schoenebeck 9 return EXIT_SUCCESS;
108     }
109    
110 schoenebeck 271 void signal_handler(int iSignal) {
111     switch (iSignal) {
112     case SIGINT: {
113     if (pthread_equal(pthread_self(), main_thread)) {
114     if (pLSCPServer) {
115     pLSCPServer->StopThread();
116     delete pLSCPServer;
117     }
118     if (pSampler) delete pSampler;
119     printf("LinuxSampler stopped due to SIGINT.\n");
120     exit(EXIT_SUCCESS);
121     }
122     return;
123 schoenebeck 53 }
124 schoenebeck 271 case SIGSEGV:
125     std::cerr << ">>> FATAL ERROR: Segmentation fault (SIGSEGV) occured! <<<\n" << std::flush;
126     break;
127     case SIGBUS:
128     std::cerr << ">>> FATAL ERROR: Access to undefined portion of a memory object (SIGBUS) occured! <<<\n" << std::flush;
129     break;
130     case SIGILL:
131     std::cerr << ">>> FATAL ERROR: Illegal instruction (SIGILL) occured! <<<\n" << std::flush;
132     break;
133     case SIGFPE:
134     std::cerr << ">>> FATAL ERROR: Erroneous arithmetic operation (SIGFPE) occured! <<<\n" << std::flush;
135     break;
136     case SIGUSR1:
137     std::cerr << ">>> User defined signal 1 (SIGUSR1) received <<<\n" << std::flush;
138     break;
139     case SIGUSR2:
140     std::cerr << ">>> User defined signal 2 (SIGUSR2) received <<<\n" << std::flush;
141     break;
142     default: { // this should never happen, as we register for the signals we want
143     std::cerr << ">>> FATAL ERROR: Unknown signal received! <<<\n" << std::flush;
144     break;
145     }
146 schoenebeck 9 }
147 schoenebeck 271 signal(iSignal, SIG_DFL); // Reinstall default handler to prevent race conditions
148     std::cerr << "Showing stack trace...\n" << std::flush;
149     StackTrace();
150     sleep(2);
151     std::cerr << "Killing LinuxSampler...\n" << std::flush;
152     kill_app(); // Use abort() if we want to generate a core dump.
153 schoenebeck 9 }
154    
155 schoenebeck 271 void kill_app() {
156     kill(main_thread, SIGKILL);
157     }
158    
159 schoenebeck 53 /*void parse_options(int argc, char **argv) {
160 schoenebeck 9 int res;
161     int option_index = 0;
162     static struct option long_options[] =
163     {
164     {"numfragments",1,0,0},
165     {"fragmentsize",1,0,0},
166 schoenebeck 20 {"volume",1,0,0},
167 schoenebeck 9 {"dls",0,0,0},
168     {"gig",0,0,0},
169 schoenebeck 20 {"instrument",1,0,0},
170     {"inputclient",1,0,0},
171 schoenebeck 33 {"alsaout",1,0,0},
172     {"jackout",1,0,0},
173     {"samplerate",1,0,0},
174 schoenebeck 35 {"server",0,0,0},
175 schoenebeck 9 {"help",0,0,0},
176     {0,0,0,0}
177     };
178    
179     while (true) {
180     res = getopt_long_only(argc, argv, "", long_options, &option_index);
181     if(res == -1) break;
182     if (res == 0) {
183     switch(option_index) {
184 schoenebeck 33 case 0: // --numfragments
185 schoenebeck 9 num_fragments = atoi(optarg);
186     break;
187 schoenebeck 33 case 1: // --fragmentsize
188 schoenebeck 9 fragmentsize = atoi(optarg);
189     break;
190 schoenebeck 33 case 2: // --volume
191 schoenebeck 20 volume = atof(optarg);
192     break;
193 schoenebeck 33 case 3: // --dls
194 schoenebeck 9 patch_format = patch_format_dls;
195     break;
196 schoenebeck 33 case 4: // --gig
197 schoenebeck 9 patch_format = patch_format_gig;
198     break;
199 schoenebeck 33 case 5: // --instrument
200 schoenebeck 20 instrument_index = atoi(optarg);
201     break;
202 schoenebeck 33 case 6: // --inputclient
203 schoenebeck 20 input_client = optarg;
204     break;
205 schoenebeck 33 case 7: // --alsaout
206     alsaout = optarg;
207     use_jack = false; // If this option is specified do not connect to jack
208     break;
209     case 8: { // --jackout
210     try {
211     String arg(optarg);
212     // remove outer apostrophes
213     arg = arg.substr(arg.find('\'') + 1, arg.rfind('\'') - (arg.find('\'') + 1));
214     // split in two arguments
215     jack_playback[0] = arg.substr(0, arg.find("\' "));
216     jack_playback[1] = arg.substr(arg.find("\' ") + 2, arg.size() - (arg.find("\' ") + 2));
217     // remove inner apostrophes
218     jack_playback[0] = jack_playback[0].substr(0, jack_playback[0].find('\''));
219     jack_playback[1] = jack_playback[1].substr(jack_playback[1].find('\'') + 1, jack_playback[1].size() - jack_playback[1].find('\''));
220     // this is the default but set it up anyway in case alsa_card was also used.
221     use_jack = true;
222     }
223     catch (...) {
224     fprintf(stderr, "Invalid argument '%s' for parameter --jackout\n", optarg);
225     exit(EXIT_FAILURE);
226     }
227     break;
228     }
229     case 9: // --samplerate
230     samplerate = atoi(optarg);
231     break;
232 schoenebeck 35 case 10: // --server
233     run_server = true;
234     break;
235     case 11: // --help
236 schoenebeck 9 printf("usage: linuxsampler [OPTIONS] <INSTRUMENTFILE>\n\n");
237 schoenebeck 20 printf("--gig loads a Gigasampler instrument\n");
238     printf("--dls loads a DLS instrument\n");
239     printf("--instrument index of the instrument in the instrument file if it\n");
240     printf(" contains more than one (default: 0)\n");
241 schoenebeck 9 printf("--numfragments sets the number of audio fragments\n");
242     printf("--fragmentsize sets the fragment size\n");
243 schoenebeck 20 printf("--volume sets global volume gain factor (a value > 1.0 means\n");
244     printf(" amplification, a value < 1.0 means attenuation,\n");
245     printf(" default: 0.25)\n");
246     printf("--inputclient connects to an Alsa sequencer input client on startup\n");
247     printf(" (e.g. 64:0 to connect to a client with ID 64 and port 0)\n");
248 schoenebeck 33 printf("--alsaout connects to the given Alsa sound device on startup\n");
249     printf(" (e.g. 0,0 to connect to hw:0,0 or plughw:0,0)\n");
250     printf("--jackout connects to the given Jack playback ports on startup\n");
251     printf(" (e.g. \"\'alsa_pcm:playback_1\' \'alsa_pcm:playback_2\'\"\n");
252     printf(" in case of stereo output)\n");
253     printf("--samplerate sets sample rate if supported by audio output system\n");
254     printf(" (e.g. 44100)\n");
255 schoenebeck 35 printf("--server launch network server for remote control\n");
256 schoenebeck 33 exit(EXIT_SUCCESS);
257 schoenebeck 9 break;
258     }
259     }
260     }
261 schoenebeck 53 }*/

  ViewVC Help
Powered by ViewVC