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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 35 - (hide annotations) (download)
Fri Mar 5 13:46:15 2004 UTC (20 years ago) by schoenebeck
File size: 11053 byte(s)
* implemented parser for the LinuxSampler control protocol (LSCP) by using
  flex / bison (where src/network/lscp.l is the input file for lex / flex
  and src/network/lscp.y is the input file for yacc / bison), parser and
  scanner can be regenerated by 'make parser'
* implemented LSCP network server (only single threaded so far), LSCP
  server will be launched if LinuxSampler was started with "--server" flag,
  implemented the following LSCP commands so far: "LOAD INSTRUMENT", "GET
  CHANNEL VOICE_COUNT", "GET CHANNEL STREAM_COUNT", "GET CHANNEL
  BUFFER_FILL", "SET CHANNEL VOLUME" and "RESET CHANNEL"
* disk thread now started within the engine

1 schoenebeck 9 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003 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 <stdio.h>
24     #include <stdlib.h>
25     #include <unistd.h>
26     #include <getopt.h>
27     #include <signal.h>
28 schoenebeck 13 #include <pthread.h>
29 schoenebeck 9
30     #include "global.h"
31     #include "diskthread.h"
32     #include "audiothread.h"
33 schoenebeck 31 #include "alsaio.h"
34     #include "jackio.h"
35 schoenebeck 9 #include "midiin.h"
36     #include "stream.h"
37     #include "RIFF.h"
38     #include "gig.h"
39 schoenebeck 35 #include "network/lscpserver.h"
40 schoenebeck 9
41     #define AUDIO_CHANNELS 2 // stereo
42     #define AUDIO_FRAGMENTS 3 // 3 fragments, if it does not work set it to 2
43     #define AUDIO_FRAGMENTSIZE 512 // each fragment has 512 frames
44     #define AUDIO_SAMPLERATE 44100 // Hz
45    
46     enum patch_format_t {
47     patch_format_unknown,
48     patch_format_gig,
49     patch_format_dls
50 schoenebeck 35 } patch_format = patch_format_unknown;
51 schoenebeck 9
52 schoenebeck 35 AudioIO* pAudioIO = NULL;
53     MidiIn* pMidiInThread = NULL;
54     LSCPServer* pLSCPServer = NULL;
55     AudioThread* pEngine = NULL;
56     uint instrument_index = 0;
57     double volume = 0.25;
58     int num_fragments = AUDIO_FRAGMENTS;
59     int fragmentsize = AUDIO_FRAGMENTSIZE;
60     uint samplerate = AUDIO_SAMPLERATE;
61     String input_client;
62     String alsaout = "0,0"; // default card
63     String jack_playback[2] = { "", "" };
64     bool use_jack = true;
65     bool run_server = false;
66     pthread_t signalhandlerthread;
67 schoenebeck 9
68     void parse_options(int argc, char **argv);
69     void signal_handler(int signal);
70    
71     int main(int argc, char **argv) {
72    
73     // setting signal handler for catching SIGINT (thus e.g. <CTRL><C>)
74 schoenebeck 13 signalhandlerthread = pthread_self();
75 schoenebeck 9 signal(SIGINT, signal_handler);
76    
77     // parse and assign command line options
78     parse_options(argc, argv);
79    
80     if (patch_format != patch_format_gig) {
81 schoenebeck 12 printf("Sorry only Gigasampler loading migrated in LinuxSampler so far, use --gig to load a .gig file!\n");
82 schoenebeck 20 printf("Use 'linuxsampler --help' to see all available options.\n");
83 schoenebeck 9 return EXIT_FAILURE;
84     }
85    
86 schoenebeck 33 int error = 1;
87 schoenebeck 31 #if HAVE_JACK
88 schoenebeck 33 if (use_jack) {
89     dmsg(1,("Initializing audio output (Jack)..."));
90     pAudioIO = new JackIO();
91     error = ((JackIO*)pAudioIO)->Initialize(AUDIO_CHANNELS, jack_playback);
92     if (error) dmsg(1,("Trying Alsa output instead.\n"));
93     }
94     #endif // HAVE_JACK
95 schoenebeck 31 if (error) {
96     dmsg(1,("Initializing audio output (Alsa)..."));
97     pAudioIO = new AlsaIO();
98 schoenebeck 33 int error = ((AlsaIO*)pAudioIO)->Initialize(AUDIO_CHANNELS, samplerate, num_fragments, fragmentsize, alsaout);
99 schoenebeck 31 if (error) return EXIT_FAILURE;
100     }
101     dmsg(1,("OK\n"));
102 schoenebeck 9
103 schoenebeck 35 AudioThread* pEngine = new AudioThread(pAudioIO);
104     MidiIn* pMidiInThread = new MidiIn(pEngine);
105    
106 schoenebeck 9 // Loading gig file
107 schoenebeck 35 result_t result = pEngine->LoadInstrument(argv[argc - 1], instrument_index);
108     if (result.type == result_type_error) return EXIT_FAILURE;
109     pEngine->Volume = volume;
110 schoenebeck 9
111 schoenebeck 12 dmsg(1,("Starting MIDI in thread..."));
112 schoenebeck 20 if (input_client.size() > 0) pMidiInThread->SubscribeToClient(input_client.c_str());
113 schoenebeck 9 pMidiInThread->StartThread();
114 schoenebeck 12 dmsg(1,("OK\n"));
115 schoenebeck 9
116     sleep(1);
117 schoenebeck 35
118 schoenebeck 12 dmsg(1,("Starting audio thread..."));
119 schoenebeck 35 pAudioIO->AssignEngine(pEngine);
120 schoenebeck 31 pAudioIO->Activate();
121 schoenebeck 12 dmsg(1,("OK\n"));
122 schoenebeck 9
123 schoenebeck 35 if (run_server) {
124     dmsg(1,("Starting network server..."));
125     pLSCPServer = new LSCPServer(pEngine);
126     pLSCPServer->StartThread();
127     dmsg(1,("OK\n"));
128     }
129    
130 schoenebeck 9 printf("LinuxSampler initialization completed.\n");
131    
132 senoner 10 while(true) {
133 schoenebeck 13 printf("Voices: %3.3d (Max: %3.3d) Streams: %3.3d (Max: %3.3d, Unused: %3.3d)\r",
134 schoenebeck 35 pEngine->ActiveVoiceCount, pEngine->ActiveVoiceCountMax,
135     pEngine->pDiskThread->ActiveStreamCount, pEngine->pDiskThread->ActiveStreamCountMax, Stream::GetUnusedStreams());
136 schoenebeck 13 fflush(stdout);
137 senoner 10 usleep(500000);
138     }
139    
140 schoenebeck 9 return EXIT_SUCCESS;
141     }
142    
143     void signal_handler(int signal) {
144 schoenebeck 20 if (pthread_equal(pthread_self(), signalhandlerthread) && signal == SIGINT) {
145 schoenebeck 9 // stop all threads
146 schoenebeck 31 if (pAudioIO) pAudioIO->Close();
147 schoenebeck 9 if (pMidiInThread) pMidiInThread->StopThread();
148    
149     // free all resources
150     if (pMidiInThread) delete pMidiInThread;
151 schoenebeck 35 if (pEngine) delete pEngine;
152 schoenebeck 9 if (pAudioIO) delete pAudioIO;
153    
154     printf("LinuxSampler stopped due to SIGINT\n");
155     exit(EXIT_SUCCESS);
156     }
157     }
158    
159     void parse_options(int argc, char **argv) {
160     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     }

  ViewVC Help
Powered by ViewVC