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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 13 - (hide annotations) (download)
Fri Nov 21 15:07:23 2003 UTC (20 years, 5 months ago) by schoenebeck
File size: 7269 byte(s)
* src/voice.cpp: fixed bug which caused a voice not free it's disk stream
  when the whole sample was already played back and the voice was going to
  free itself resulting in outage of unused disk streams after a while
* src/audioio.cpp: implemented automatic fallback to ALSA plughw when the
  sound card doesn't support one of the hardware parameters
* src/linuxsampler.cpp: solved segmentation fault issue when receiving a
  SIGINT which was caused due to the fact that all threads entered the
  signal handler (there still seems to occur a segfault on some certain
  circumstances though)
* added print out of all-time maximum usage of voices and streams and the
  current number of unused streams
* src/thread.cpp: the StopThread() method will now block until the
  associated thread actually stopped it's execution

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 "audioio.h"
32     #include "diskthread.h"
33     #include "audiothread.h"
34     #include "midiin.h"
35     #include "stream.h"
36     #include "RIFF.h"
37     #include "gig.h"
38    
39     #define AUDIO_CHANNELS 2 // stereo
40     #define AUDIO_FRAGMENTS 3 // 3 fragments, if it does not work set it to 2
41     #define AUDIO_FRAGMENTSIZE 512 // each fragment has 512 frames
42     #define AUDIO_SAMPLERATE 44100 // Hz
43    
44     enum patch_format_t {
45     patch_format_unknown,
46     patch_format_gig,
47     patch_format_dls
48     } patch_format;
49    
50     AudioIO* pAudioIO;
51     DiskThread* pDiskThread;
52     AudioThread* pAudioThread;
53     MidiIn* pMidiInThread;
54     RIFF::File* pRIFF;
55     gig::File* pGig;
56     gig::Instrument* pInstrument;
57 schoenebeck 12 int num_fragments;
58     int fragmentsize;
59 schoenebeck 13 pthread_t signalhandlerthread;
60 schoenebeck 9
61     void parse_options(int argc, char **argv);
62     void signal_handler(int signal);
63    
64     int main(int argc, char **argv) {
65     pAudioIO = NULL;
66     pRIFF = NULL;
67     pGig = NULL;
68    
69     // setting signal handler for catching SIGINT (thus e.g. <CTRL><C>)
70 schoenebeck 13 signalhandlerthread = pthread_self();
71 schoenebeck 9 signal(SIGINT, signal_handler);
72    
73     patch_format = patch_format_unknown;
74     num_fragments = AUDIO_FRAGMENTS;
75     fragmentsize = AUDIO_FRAGMENTSIZE;
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 9 return EXIT_FAILURE;
83     }
84    
85 schoenebeck 12 dmsg(1,("Initializing audio output..."));
86 schoenebeck 9 pAudioIO = new AudioIO();
87     int error = pAudioIO->Initialize(AUDIO_CHANNELS, AUDIO_SAMPLERATE, num_fragments, fragmentsize);
88     if (error) return EXIT_FAILURE;
89 schoenebeck 12 dmsg(1,("OK\n"));
90 schoenebeck 9
91     // Loading gig file
92     try {
93     printf("Loading gig file...");
94     fflush(stdout);
95     pRIFF = new RIFF::File(argv[argc - 1]);
96     pGig = new gig::File(pRIFF);
97     pInstrument = pGig->GetFirstInstrument();
98     pGig->GetFirstSample(); // just to complete instrument loading before we enter the realtime part
99     printf("OK\n");
100     fflush(stdout);
101     }
102     catch (RIFF::Exception e) {
103     e.PrintMessage();
104     return EXIT_FAILURE;
105     }
106     catch (...) {
107     printf("Unknown exception while trying to parse gig file.\n");
108     return EXIT_FAILURE;
109     }
110    
111     DiskThread* pDiskThread = new DiskThread(((pAudioIO->FragmentSize << MAX_PITCH) << 1) + 3); //FIXME: assuming stereo
112     AudioThread* pAudioThread = new AudioThread(pAudioIO, pDiskThread, pInstrument);
113     MidiIn* pMidiInThread = new MidiIn(pAudioThread);
114    
115 schoenebeck 12 dmsg(1,("Starting disk thread..."));
116 schoenebeck 9 pDiskThread->StartThread();
117 schoenebeck 12 dmsg(1,("OK\n"));
118     dmsg(1,("Starting MIDI in thread..."));
119 schoenebeck 9 pMidiInThread->StartThread();
120 schoenebeck 12 dmsg(1,("OK\n"));
121 schoenebeck 9
122     sleep(1);
123 schoenebeck 12 dmsg(1,("Starting audio thread..."));
124 schoenebeck 9 pAudioThread->StartThread();
125 schoenebeck 12 dmsg(1,("OK\n"));
126 schoenebeck 9
127     printf("LinuxSampler initialization completed.\n");
128    
129 senoner 10 while(true) {
130 schoenebeck 13 printf("Voices: %3.3d (Max: %3.3d) Streams: %3.3d (Max: %3.3d, Unused: %3.3d)\r",
131     pAudioThread->ActiveVoiceCount, pAudioThread->ActiveVoiceCountMax,
132     pDiskThread->ActiveStreamCount, pDiskThread->ActiveStreamCountMax, Stream::GetUnusedStreams());
133     fflush(stdout);
134 senoner 10 usleep(500000);
135     }
136    
137 schoenebeck 9 return EXIT_SUCCESS;
138     }
139    
140     void signal_handler(int signal) {
141 schoenebeck 13 if (pthread_equal(pthread_self(), signalhandlerthread) && signal == SIGINT) {
142 schoenebeck 9 // stop all threads
143     if (pMidiInThread) pMidiInThread->StopThread();
144     if (pAudioThread) pAudioThread->StopThread();
145     if (pDiskThread) pDiskThread->StopThread();
146    
147     // free all resources
148     if (pMidiInThread) delete pMidiInThread;
149     if (pAudioThread) delete pAudioThread;
150     if (pDiskThread) delete pDiskThread;
151     if (pGig) delete pGig;
152     if (pRIFF) delete pRIFF;
153     if (pAudioIO) delete pAudioIO;
154    
155     printf("LinuxSampler stopped due to SIGINT\n");
156     exit(EXIT_SUCCESS);
157     }
158     }
159    
160     void parse_options(int argc, char **argv) {
161     int res;
162     int option_index = 0;
163     static struct option long_options[] =
164     {
165     {"numfragments",1,0,0},
166     {"fragmentsize",1,0,0},
167     {"dls",0,0,0},
168     {"gig",0,0,0},
169     {"help",0,0,0},
170     {0,0,0,0}
171     };
172    
173     while (true) {
174     res = getopt_long_only(argc, argv, "", long_options, &option_index);
175     if(res == -1) break;
176     if (res == 0) {
177     switch(option_index) {
178     case 0:
179     num_fragments = atoi(optarg);
180     break;
181     case 1:
182     fragmentsize = atoi(optarg);
183     break;
184     case 2:
185     patch_format = patch_format_dls;
186     break;
187     case 3:
188     patch_format = patch_format_gig;
189     break;
190     case 4:
191     printf("usage: linuxsampler [OPTIONS] <INSTRUMENTFILE>\n\n");
192     printf("--numfragments sets the number of audio fragments\n");
193     printf("--fragmentsize sets the fragment size\n");
194     printf("--dls loads a DLS instrument\n");
195     printf("--gig loads a Gigasampler instrument\n");
196     exit(0);
197     break;
198     }
199     }
200     }
201     }

  ViewVC Help
Powered by ViewVC