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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Sun Jan 18 20:31:31 2004 UTC (20 years, 3 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 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 schoenebeck 20 #include <string>
31    
32 schoenebeck 9 #include "global.h"
33     #include "diskthread.h"
34     #include "audiothread.h"
35 schoenebeck 31 #include "alsaio.h"
36     #include "jackio.h"
37 schoenebeck 9 #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 schoenebeck 20 uint instrument_index;
61     double volume;
62 schoenebeck 12 int num_fragments;
63     int fragmentsize;
64 schoenebeck 20 std::string input_client;
65 schoenebeck 13 pthread_t signalhandlerthread;
66 schoenebeck 9
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 schoenebeck 13 signalhandlerthread = pthread_self();
77 schoenebeck 9 signal(SIGINT, signal_handler);
78    
79     patch_format = patch_format_unknown;
80 schoenebeck 20 instrument_index = 0;
81 schoenebeck 9 num_fragments = AUDIO_FRAGMENTS;
82     fragmentsize = AUDIO_FRAGMENTSIZE;
83 schoenebeck 20 volume = 0.25; // default volume
84 schoenebeck 9
85     // parse and assign command line options
86     parse_options(argc, argv);
87    
88     if (patch_format != patch_format_gig) {
89 schoenebeck 12 printf("Sorry only Gigasampler loading migrated in LinuxSampler so far, use --gig to load a .gig file!\n");
90 schoenebeck 20 printf("Use 'linuxsampler --help' to see all available options.\n");
91 schoenebeck 9 return EXIT_FAILURE;
92     }
93    
94 schoenebeck 31 #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 schoenebeck 9 if (error) return EXIT_FAILURE;
111 schoenebeck 12 dmsg(1,("OK\n"));
112 schoenebeck 31 #endif // HAVE_JACK
113 schoenebeck 9
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 schoenebeck 20 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 schoenebeck 9 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 schoenebeck 31 DiskThread* pDiskThread = new DiskThread(((pAudioIO->MaxSamplesPerCycle() << MAX_PITCH) << 1) + 6); //FIXME: assuming stereo
139 schoenebeck 9 AudioThread* pAudioThread = new AudioThread(pAudioIO, pDiskThread, pInstrument);
140     MidiIn* pMidiInThread = new MidiIn(pAudioThread);
141    
142 schoenebeck 12 dmsg(1,("Starting disk thread..."));
143 schoenebeck 9 pDiskThread->StartThread();
144 schoenebeck 12 dmsg(1,("OK\n"));
145     dmsg(1,("Starting MIDI in thread..."));
146 schoenebeck 20 if (input_client.size() > 0) pMidiInThread->SubscribeToClient(input_client.c_str());
147 schoenebeck 9 pMidiInThread->StartThread();
148 schoenebeck 12 dmsg(1,("OK\n"));
149 schoenebeck 9
150     sleep(1);
151 schoenebeck 12 dmsg(1,("Starting audio thread..."));
152 schoenebeck 20 pAudioThread->Volume = volume;
153 schoenebeck 31 pAudioIO->AssignEngine(pAudioThread);
154     pAudioIO->Activate();
155 schoenebeck 12 dmsg(1,("OK\n"));
156 schoenebeck 9
157     printf("LinuxSampler initialization completed.\n");
158    
159 senoner 10 while(true) {
160 schoenebeck 13 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 senoner 10 usleep(500000);
165     }
166    
167 schoenebeck 9 return EXIT_SUCCESS;
168     }
169    
170     void signal_handler(int signal) {
171 schoenebeck 20 if (pthread_equal(pthread_self(), signalhandlerthread) && signal == SIGINT) {
172 schoenebeck 9 // stop all threads
173 schoenebeck 31 if (pAudioIO) pAudioIO->Close();
174 schoenebeck 9 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 schoenebeck 20 {"volume",1,0,0},
198 schoenebeck 9 {"dls",0,0,0},
199     {"gig",0,0,0},
200 schoenebeck 20 {"instrument",1,0,0},
201     {"inputclient",1,0,0},
202 schoenebeck 9 {"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 schoenebeck 20 volume = atof(optarg);
219     break;
220     case 3:
221 schoenebeck 9 patch_format = patch_format_dls;
222     break;
223 schoenebeck 20 case 4:
224 schoenebeck 9 patch_format = patch_format_gig;
225     break;
226 schoenebeck 20 case 5:
227     instrument_index = atoi(optarg);
228     break;
229     case 6:
230     input_client = optarg;
231     break;
232     case 7:
233 schoenebeck 9 printf("usage: linuxsampler [OPTIONS] <INSTRUMENTFILE>\n\n");
234 schoenebeck 20 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 schoenebeck 9 printf("--numfragments sets the number of audio fragments\n");
239     printf("--fragmentsize sets the fragment size\n");
240 schoenebeck 20 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 schoenebeck 9 exit(0);
246     break;
247     }
248     }
249     }
250     }

  ViewVC Help
Powered by ViewVC