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

Contents of /linuxsampler/trunk/src/linuxsampler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Sun Jan 18 20:31:31 2004 UTC (20 years, 2 months ago) by schoenebeck
File size: 9494 byte(s)
* Added JACK support: Audio rendering process is now callback based and
  independant of used audio output system. Interfaces to other audio output
  systems can be added by creating a class derived from abstract base class
  'AudioIO' and embedding the new class into linuxsampler.cpp.
* src/audiothread.cpp: applied patch from Vladimir Senkov which fixes
  hanging notes in conjunction with the sustain pedal

1 /***************************************************************************
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 #include <pthread.h>
29
30 #include <string>
31
32 #include "global.h"
33 #include "diskthread.h"
34 #include "audiothread.h"
35 #include "alsaio.h"
36 #include "jackio.h"
37 #include "midiin.h"
38 #include "stream.h"
39 #include "RIFF.h"
40 #include "gig.h"
41
42 #define AUDIO_CHANNELS 2 // stereo
43 #define AUDIO_FRAGMENTS 3 // 3 fragments, if it does not work set it to 2
44 #define AUDIO_FRAGMENTSIZE 512 // each fragment has 512 frames
45 #define AUDIO_SAMPLERATE 44100 // Hz
46
47 enum patch_format_t {
48 patch_format_unknown,
49 patch_format_gig,
50 patch_format_dls
51 } patch_format;
52
53 AudioIO* pAudioIO;
54 DiskThread* pDiskThread;
55 AudioThread* pAudioThread;
56 MidiIn* pMidiInThread;
57 RIFF::File* pRIFF;
58 gig::File* pGig;
59 gig::Instrument* pInstrument;
60 uint instrument_index;
61 double volume;
62 int num_fragments;
63 int fragmentsize;
64 std::string input_client;
65 pthread_t signalhandlerthread;
66
67 void parse_options(int argc, char **argv);
68 void signal_handler(int signal);
69
70 int main(int argc, char **argv) {
71 pAudioIO = NULL;
72 pRIFF = NULL;
73 pGig = NULL;
74
75 // setting signal handler for catching SIGINT (thus e.g. <CTRL><C>)
76 signalhandlerthread = pthread_self();
77 signal(SIGINT, signal_handler);
78
79 patch_format = patch_format_unknown;
80 instrument_index = 0;
81 num_fragments = AUDIO_FRAGMENTS;
82 fragmentsize = AUDIO_FRAGMENTSIZE;
83 volume = 0.25; // default volume
84
85 // parse and assign command line options
86 parse_options(argc, argv);
87
88 if (patch_format != patch_format_gig) {
89 printf("Sorry only Gigasampler loading migrated in LinuxSampler so far, use --gig to load a .gig file!\n");
90 printf("Use 'linuxsampler --help' to see all available options.\n");
91 return EXIT_FAILURE;
92 }
93
94 #if HAVE_JACK
95 dmsg(1,("Initializing audio output (Jack)..."));
96 pAudioIO = new JackIO();
97 int error = ((JackIO*)pAudioIO)->Initialize(AUDIO_CHANNELS);
98 if (error) {
99 dmsg(1,("Trying Alsa output instead.\n"));
100 dmsg(1,("Initializing audio output (Alsa)..."));
101 pAudioIO = new AlsaIO();
102 int error = ((AlsaIO*)pAudioIO)->Initialize(AUDIO_CHANNELS, AUDIO_SAMPLERATE, num_fragments, fragmentsize);
103 if (error) return EXIT_FAILURE;
104 }
105 dmsg(1,("OK\n"));
106 #else // Alsa only
107 dmsg(1,("Initializing audio output (Alsa)..."));
108 pAudioIO = new AlsaIO();
109 int error = ((AlsaIO*)pAudioIO)->Initialize(AUDIO_CHANNELS, AUDIO_SAMPLERATE, num_fragments, fragmentsize);
110 if (error) return EXIT_FAILURE;
111 dmsg(1,("OK\n"));
112 #endif // HAVE_JACK
113
114 // Loading gig file
115 try {
116 printf("Loading gig file...");
117 fflush(stdout);
118 pRIFF = new RIFF::File(argv[argc - 1]);
119 pGig = new gig::File(pRIFF);
120 pInstrument = pGig->GetInstrument(instrument_index);
121 if (!pInstrument) {
122 printf("there's no instrument with index %d.\n", instrument_index);
123 exit(EXIT_FAILURE);
124 }
125 pGig->GetFirstSample(); // just to complete instrument loading before we enter the realtime part
126 printf("OK\n");
127 fflush(stdout);
128 }
129 catch (RIFF::Exception e) {
130 e.PrintMessage();
131 return EXIT_FAILURE;
132 }
133 catch (...) {
134 printf("Unknown exception while trying to parse gig file.\n");
135 return EXIT_FAILURE;
136 }
137
138 DiskThread* pDiskThread = new DiskThread(((pAudioIO->MaxSamplesPerCycle() << MAX_PITCH) << 1) + 6); //FIXME: assuming stereo
139 AudioThread* pAudioThread = new AudioThread(pAudioIO, pDiskThread, pInstrument);
140 MidiIn* pMidiInThread = new MidiIn(pAudioThread);
141
142 dmsg(1,("Starting disk thread..."));
143 pDiskThread->StartThread();
144 dmsg(1,("OK\n"));
145 dmsg(1,("Starting MIDI in thread..."));
146 if (input_client.size() > 0) pMidiInThread->SubscribeToClient(input_client.c_str());
147 pMidiInThread->StartThread();
148 dmsg(1,("OK\n"));
149
150 sleep(1);
151 dmsg(1,("Starting audio thread..."));
152 pAudioThread->Volume = volume;
153 pAudioIO->AssignEngine(pAudioThread);
154 pAudioIO->Activate();
155 dmsg(1,("OK\n"));
156
157 printf("LinuxSampler initialization completed.\n");
158
159 while(true) {
160 printf("Voices: %3.3d (Max: %3.3d) Streams: %3.3d (Max: %3.3d, Unused: %3.3d)\r",
161 pAudioThread->ActiveVoiceCount, pAudioThread->ActiveVoiceCountMax,
162 pDiskThread->ActiveStreamCount, pDiskThread->ActiveStreamCountMax, Stream::GetUnusedStreams());
163 fflush(stdout);
164 usleep(500000);
165 }
166
167 return EXIT_SUCCESS;
168 }
169
170 void signal_handler(int signal) {
171 if (pthread_equal(pthread_self(), signalhandlerthread) && signal == SIGINT) {
172 // stop all threads
173 if (pAudioIO) pAudioIO->Close();
174 if (pMidiInThread) pMidiInThread->StopThread();
175 if (pDiskThread) pDiskThread->StopThread();
176
177 // free all resources
178 if (pMidiInThread) delete pMidiInThread;
179 if (pAudioThread) delete pAudioThread;
180 if (pDiskThread) delete pDiskThread;
181 if (pGig) delete pGig;
182 if (pRIFF) delete pRIFF;
183 if (pAudioIO) delete pAudioIO;
184
185 printf("LinuxSampler stopped due to SIGINT\n");
186 exit(EXIT_SUCCESS);
187 }
188 }
189
190 void parse_options(int argc, char **argv) {
191 int res;
192 int option_index = 0;
193 static struct option long_options[] =
194 {
195 {"numfragments",1,0,0},
196 {"fragmentsize",1,0,0},
197 {"volume",1,0,0},
198 {"dls",0,0,0},
199 {"gig",0,0,0},
200 {"instrument",1,0,0},
201 {"inputclient",1,0,0},
202 {"help",0,0,0},
203 {0,0,0,0}
204 };
205
206 while (true) {
207 res = getopt_long_only(argc, argv, "", long_options, &option_index);
208 if(res == -1) break;
209 if (res == 0) {
210 switch(option_index) {
211 case 0:
212 num_fragments = atoi(optarg);
213 break;
214 case 1:
215 fragmentsize = atoi(optarg);
216 break;
217 case 2:
218 volume = atof(optarg);
219 break;
220 case 3:
221 patch_format = patch_format_dls;
222 break;
223 case 4:
224 patch_format = patch_format_gig;
225 break;
226 case 5:
227 instrument_index = atoi(optarg);
228 break;
229 case 6:
230 input_client = optarg;
231 break;
232 case 7:
233 printf("usage: linuxsampler [OPTIONS] <INSTRUMENTFILE>\n\n");
234 printf("--gig loads a Gigasampler instrument\n");
235 printf("--dls loads a DLS instrument\n");
236 printf("--instrument index of the instrument in the instrument file if it\n");
237 printf(" contains more than one (default: 0)\n");
238 printf("--numfragments sets the number of audio fragments\n");
239 printf("--fragmentsize sets the fragment size\n");
240 printf("--volume sets global volume gain factor (a value > 1.0 means\n");
241 printf(" amplification, a value < 1.0 means attenuation,\n");
242 printf(" default: 0.25)\n");
243 printf("--inputclient connects to an Alsa sequencer input client on startup\n");
244 printf(" (e.g. 64:0 to connect to a client with ID 64 and port 0)\n");
245 exit(0);
246 break;
247 }
248 }
249 }
250 }

  ViewVC Help
Powered by ViewVC