/[svn]/linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceAlsa.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceAlsa.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 214 by schoenebeck, Sat Aug 14 23:00:44 2004 UTC revision 1599 by schoenebeck, Fri Dec 28 15:47:33 2007 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6     *   Copyright (C) 2005 - 2007 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 25  Line 26 
26    
27  namespace LinuxSampler {  namespace LinuxSampler {
28    
     REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDeviceAlsa);  
   
     /* Common parameters for now they'll have to be registered here. */  
     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterActive);  
     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterSampleRate);  
     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterChannels);  
   
     /* Driver specific parameters */  
     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterCard);  
     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragments);  
     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragmentSize);  
   
   
   
29  // *************** ParameterCard ***************  // *************** ParameterCard ***************
30  // *  // *
31    
# Line 46  namespace LinuxSampler { Line 33  namespace LinuxSampler {
33          InitWithDefault(); // use default card          InitWithDefault(); // use default card
34      }      }
35    
36      AudioOutputDeviceAlsa::ParameterCard::ParameterCard(String s) throw (LinuxSamplerException) : DeviceCreationParameterString(s) {      AudioOutputDeviceAlsa::ParameterCard::ParameterCard(String s) throw (Exception) : DeviceCreationParameterString(s) {
         SetValue(s); // try to use given card  
37      }      }
38    
39      String AudioOutputDeviceAlsa::ParameterCard::Description() {      String AudioOutputDeviceAlsa::ParameterCard::Description() {
# Line 68  namespace LinuxSampler { Line 54  namespace LinuxSampler {
54    
55      optional<String> AudioOutputDeviceAlsa::ParameterCard::DefaultAsString(std::map<String,String> Parameters) {      optional<String> AudioOutputDeviceAlsa::ParameterCard::DefaultAsString(std::map<String,String> Parameters) {
56          std::vector<String> cards = PossibilitiesAsString(Parameters);          std::vector<String> cards = PossibilitiesAsString(Parameters);
57          if (cards.empty()) throw LinuxSamplerException("AudioOutputDeviceAlsa: Can't find any card");          if (cards.empty()) throw Exception("AudioOutputDeviceAlsa: Can't find any card");
58          return cards[0]; // first card by default          return cards[0]; // first card by default
59      }      }
60    
# Line 100  namespace LinuxSampler { Line 86  namespace LinuxSampler {
86          return CardNames;          return CardNames;
87      }      }
88    
89      void AudioOutputDeviceAlsa::ParameterCard::OnSetValue(String s) throw (LinuxSamplerException) {      void AudioOutputDeviceAlsa::ParameterCard::OnSetValue(String s) throw (Exception) {
90          // not posssible, as parameter is fix          // not posssible, as parameter is fix
91      }      }
92    
93      String AudioOutputDeviceAlsa::ParameterCard::Name() {      String AudioOutputDeviceAlsa::ParameterCard::Name() {
94          return "card";          return "CARD";
95        }
96    
97    
98    
99    // *************** ParameterSampleRate ***************
100    // *
101    
102        AudioOutputDeviceAlsa::ParameterSampleRate::ParameterSampleRate() : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate() {
103        }
104    
105        AudioOutputDeviceAlsa::ParameterSampleRate::ParameterSampleRate(String s) : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate(s) {
106        }
107    
108        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::ParameterSampleRate::DependsAsParameters() {
109            static ParameterCard card;
110            std::map<String,DeviceCreationParameter*> dependencies;
111            dependencies[card.Name()] = &card;
112            return dependencies;
113        }
114    
115        optional<int> AudioOutputDeviceAlsa::ParameterSampleRate::DefaultAsInt(std::map<String,String> Parameters) {
116            if (!Parameters.count("CARD")) return optional<int>::nothing;
117    
118            // obtain information from given sound card
119            ParameterCard card(Parameters["CARD"]);
120            String pcm_name = "hw:" + card.ValueAsString();
121            snd_pcm_t* pcm_handle = NULL;
122            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
123            snd_pcm_hw_params_t* hwparams;
124            snd_pcm_hw_params_alloca(&hwparams);
125            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
126                snd_pcm_close(pcm_handle);
127                return optional<int>::nothing;
128            }
129            uint rate = 44100;
130            if (snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, NULL) < 0) {
131                snd_pcm_close(pcm_handle);
132                return optional<int>::nothing;
133            }
134            snd_pcm_close(pcm_handle);
135            return rate;
136        }
137    
138        optional<int> AudioOutputDeviceAlsa::ParameterSampleRate::RangeMinAsInt(std::map<String,String> Parameters) {
139            if (!Parameters.count("CARD")) return optional<int>::nothing;
140    
141            // obtain information from given sound card
142            ParameterCard card(Parameters["CARD"]);
143            String pcm_name = "hw:" + card.ValueAsString();
144            snd_pcm_t* pcm_handle = NULL;
145            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
146            snd_pcm_hw_params_t* hwparams;
147            snd_pcm_hw_params_alloca(&hwparams);
148            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
149                snd_pcm_close(pcm_handle);
150                return optional<int>::nothing;
151            }
152            uint rate;
153            if (snd_pcm_hw_params_get_rate_min(hwparams, &rate, NULL) < 0) {
154                snd_pcm_close(pcm_handle);
155                return optional<int>::nothing;
156            }
157            snd_pcm_close(pcm_handle);
158            return rate;
159        }
160    
161        optional<int> AudioOutputDeviceAlsa::ParameterSampleRate::RangeMaxAsInt(std::map<String,String> Parameters) {
162            if (!Parameters.count("CARD")) return optional<int>::nothing;
163    
164            // obtain information from given sound card
165            String pcm_name       = "hw:" + Parameters["CARD"];
166            snd_pcm_t* pcm_handle = NULL;
167            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
168            snd_pcm_hw_params_t* hwparams;
169            snd_pcm_hw_params_alloca(&hwparams);
170            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
171                snd_pcm_close(pcm_handle);
172                return optional<int>::nothing;
173            }
174            uint rate;
175            if (snd_pcm_hw_params_get_rate_max(hwparams, &rate, NULL) < 0) {
176                snd_pcm_close(pcm_handle);
177                return optional<int>::nothing;
178            }
179            snd_pcm_close(pcm_handle);
180            return rate;
181        }
182    
183    
184    
185    // *************** ParameterChannels ***************
186    // *
187    
188        AudioOutputDeviceAlsa::ParameterChannels::ParameterChannels() : AudioOutputDevice::ParameterChannels::ParameterChannels() {
189            //InitWithDefault();
190            // could not determine default value? ...
191            //if (ValueAsInt() == 0) SetValue(2); // ... then (try) a common value
192        }
193    
194        AudioOutputDeviceAlsa::ParameterChannels::ParameterChannels(String s) : AudioOutputDevice::ParameterChannels::ParameterChannels(s) {
195        }
196    
197        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::ParameterChannels::DependsAsParameters() {
198            static ParameterCard card;
199            std::map<String,DeviceCreationParameter*> dependencies;
200            dependencies[card.Name()] = &card;
201            return dependencies;
202        }
203    
204        optional<int> AudioOutputDeviceAlsa::ParameterChannels::DefaultAsInt(std::map<String,String> Parameters) {
205            if (!Parameters.count("CARD")) return optional<int>::nothing;
206    
207            // obtain information from given sound card
208            ParameterCard card(Parameters["CARD"]);
209            String pcm_name = "hw:" + card.ValueAsString();
210            snd_pcm_t* pcm_handle = NULL;
211            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
212            snd_pcm_hw_params_t* hwparams;
213            snd_pcm_hw_params_alloca(&hwparams);
214            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
215                snd_pcm_close(pcm_handle);
216                return optional<int>::nothing;
217            }
218            uint channels = 2;
219            if (snd_pcm_hw_params_set_channels_near(pcm_handle, hwparams, &channels) < 0) {
220                snd_pcm_close(pcm_handle);
221                return optional<int>::nothing;
222            }
223            snd_pcm_close(pcm_handle);
224            return channels;
225        }
226    
227        optional<int> AudioOutputDeviceAlsa::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) {
228            uint channels = 1;
229            if (!Parameters.count("CARD")) return channels;
230    
231            // obtain information from given sound card
232            ParameterCard card(Parameters["CARD"]);
233            String pcm_name = "hw:" + card.ValueAsString();
234            snd_pcm_t* pcm_handle = NULL;
235            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return channels;
236            snd_pcm_hw_params_t* hwparams;
237            snd_pcm_hw_params_alloca(&hwparams);
238            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
239                snd_pcm_close(pcm_handle);
240                return channels;
241            }
242    
243            if (snd_pcm_hw_params_get_channels_min(hwparams, &channels) < 0) {
244                snd_pcm_close(pcm_handle);
245                return channels;
246            }
247            snd_pcm_close(pcm_handle);
248            return channels;
249        }
250    
251        optional<int> AudioOutputDeviceAlsa::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {
252            uint channels = 100;
253            if (!Parameters.count("CARD")) return optional<int>::nothing;
254    
255            // obtain information from given sound card
256            String pcm_name       = "hw:" + Parameters["CARD"];
257            snd_pcm_t* pcm_handle = NULL;
258            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0)
259                return optional<int>::nothing;
260            snd_pcm_hw_params_t* hwparams;
261            snd_pcm_hw_params_alloca(&hwparams);
262            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
263                snd_pcm_close(pcm_handle);
264                return optional<int>::nothing;
265            }
266    
267            if (snd_pcm_hw_params_get_channels_max(hwparams, &channels) < 0) {
268                snd_pcm_close(pcm_handle);
269                return optional<int>::nothing;
270            }
271            snd_pcm_close(pcm_handle);
272            return channels;
273      }      }
274    
275    
# Line 117  namespace LinuxSampler { Line 281  namespace LinuxSampler {
281          InitWithDefault();          InitWithDefault();
282      }      }
283    
284      AudioOutputDeviceAlsa::ParameterFragments::ParameterFragments(String s) throw (LinuxSamplerException) : DeviceCreationParameterInt(s) {      AudioOutputDeviceAlsa::ParameterFragments::ParameterFragments(String s) throw (Exception) : DeviceCreationParameterInt(s) {
285      }      }
286    
287      String AudioOutputDeviceAlsa::ParameterFragments::Description() {      String AudioOutputDeviceAlsa::ParameterFragments::Description() {
# Line 140  namespace LinuxSampler { Line 304  namespace LinuxSampler {
304      }      }
305    
306      optional<int> AudioOutputDeviceAlsa::ParameterFragments::DefaultAsInt(std::map<String,String> Parameters) {      optional<int> AudioOutputDeviceAlsa::ParameterFragments::DefaultAsInt(std::map<String,String> Parameters) {
307          return 2; // until done          if (!Parameters.count("CARD")) return optional<int>::nothing;
308    
309            // obtain information from given sound card
310            ParameterCard card(Parameters["CARD"]);
311            String pcm_name = "hw:" + card.ValueAsString();
312            snd_pcm_t* pcm_handle = NULL;
313            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
314            snd_pcm_hw_params_t* hwparams;
315            snd_pcm_hw_params_alloca(&hwparams);
316            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
317                snd_pcm_close(pcm_handle);
318                return optional<int>::nothing;
319            }
320            uint segs = 2;
321            if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &segs, NULL) < 0) {
322                snd_pcm_close(pcm_handle);
323                return optional<int>::nothing;
324            }
325            snd_pcm_close(pcm_handle);
326            return segs;
327      }      }
328    
329      optional<int> AudioOutputDeviceAlsa::ParameterFragments::RangeMinAsInt(std::map<String,String> Parameters) {      optional<int> AudioOutputDeviceAlsa::ParameterFragments::RangeMinAsInt(std::map<String,String> Parameters) {
330          return optional<int>::nothing;          if (!Parameters.count("CARD")) return optional<int>::nothing;
331    
332            // obtain information from given sound card
333            ParameterCard card(Parameters["CARD"]);
334            String pcm_name = "hw:" + card.ValueAsString();
335            snd_pcm_t* pcm_handle = NULL;
336            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
337            snd_pcm_hw_params_t* hwparams;
338            snd_pcm_hw_params_alloca(&hwparams);
339            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
340                snd_pcm_close(pcm_handle);
341                return optional<int>::nothing;
342            }
343            int dir = 0;
344            uint periods_min;
345            if (snd_pcm_hw_params_get_periods_min(hwparams, &periods_min, &dir) < 0) {
346                snd_pcm_close(pcm_handle);
347                return optional<int>::nothing;
348            }
349            snd_pcm_close(pcm_handle);
350            return (int) periods_min;
351      }      }
352    
353      optional<int> AudioOutputDeviceAlsa::ParameterFragments::RangeMaxAsInt(std::map<String,String> Parameters) {      optional<int> AudioOutputDeviceAlsa::ParameterFragments::RangeMaxAsInt(std::map<String,String> Parameters) {
354          return optional<int>::nothing;          if (!Parameters.count("CARD")) return optional<int>::nothing;
355    
356            // obtain information from given sound card
357            ParameterCard card(Parameters["CARD"]);
358            String pcm_name = "hw:" + card.ValueAsString();
359            snd_pcm_t* pcm_handle = NULL;
360            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
361            snd_pcm_hw_params_t* hwparams;
362            snd_pcm_hw_params_alloca(&hwparams);
363            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
364                snd_pcm_close(pcm_handle);
365                return optional<int>::nothing;
366            }
367            int dir = 0;
368            uint periods_max;
369            if (snd_pcm_hw_params_get_periods_max(hwparams, &periods_max, &dir) < 0) {
370                snd_pcm_close(pcm_handle);
371                return optional<int>::nothing;
372            }
373            snd_pcm_close(pcm_handle);
374            return (int) periods_max;
375      }      }
376    
377      std::vector<int> AudioOutputDeviceAlsa::ParameterFragments::PossibilitiesAsInt(std::map<String,String> Parameters) {      std::vector<int> AudioOutputDeviceAlsa::ParameterFragments::PossibilitiesAsInt(std::map<String,String> Parameters) {
378          return std::vector<int>();          return std::vector<int>();
379      }      }
380    
381      void AudioOutputDeviceAlsa::ParameterFragments::OnSetValue(int i) throw (LinuxSamplerException) {      void AudioOutputDeviceAlsa::ParameterFragments::OnSetValue(int i) throw (Exception) {
382          // not posssible, as parameter is fix          // not posssible, as parameter is fix
383      }      }
384    
385      String AudioOutputDeviceAlsa::ParameterFragments::Name() {      String AudioOutputDeviceAlsa::ParameterFragments::Name() {
386          return "fragments";          return "FRAGMENTS";
387      }      }
388    
389    
# Line 172  namespace LinuxSampler { Line 395  namespace LinuxSampler {
395          InitWithDefault();          InitWithDefault();
396      }      }
397    
398      AudioOutputDeviceAlsa::ParameterFragmentSize::ParameterFragmentSize(String s) throw (LinuxSamplerException) : DeviceCreationParameterInt(s) {      AudioOutputDeviceAlsa::ParameterFragmentSize::ParameterFragmentSize(String s) throw (Exception) : DeviceCreationParameterInt(s) {
399      }      }
400    
401      String AudioOutputDeviceAlsa::ParameterFragmentSize::Description() {      String AudioOutputDeviceAlsa::ParameterFragmentSize::Description() {
# Line 195  namespace LinuxSampler { Line 418  namespace LinuxSampler {
418      }      }
419    
420      optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) {      optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) {
421          return 128; // until done          if (!Parameters.count("CARD")) return optional<int>::nothing;
422    
423            // obtain information from given sound card
424            ParameterCard card(Parameters["CARD"]);
425            String pcm_name = "hw:" + card.ValueAsString();
426            snd_pcm_t* pcm_handle = NULL;
427            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
428            snd_pcm_hw_params_t* hwparams;
429            snd_pcm_hw_params_alloca(&hwparams);
430            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
431                snd_pcm_close(pcm_handle);
432                return optional<int>::nothing;
433            }
434            snd_pcm_uframes_t size = 128;
435            if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &size, NULL) < 0) {
436                snd_pcm_close(pcm_handle);
437                return optional<int>::nothing;
438            }
439            snd_pcm_close(pcm_handle);
440            return size;
441      }      }
442    
443      optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) {      optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) {
444          return optional<int>::nothing;          if (!Parameters.count("CARD")) return optional<int>::nothing;
445    
446            // obtain information from given sound card
447            ParameterCard card(Parameters["CARD"]);
448            String pcm_name = "hw:" + card.ValueAsString();
449            snd_pcm_t* pcm_handle = NULL;
450            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
451            snd_pcm_hw_params_t* hwparams;
452            snd_pcm_hw_params_alloca(&hwparams);
453            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
454                snd_pcm_close(pcm_handle);
455                return optional<int>::nothing;
456            }
457            int dir = 0;
458            unsigned long period_size_min;
459            if (snd_pcm_hw_params_get_period_size_min(hwparams, &period_size_min, &dir) < 0) {
460                snd_pcm_close(pcm_handle);
461                return optional<int>::nothing;
462            }
463            snd_pcm_close(pcm_handle);
464            return (int) period_size_min;
465      }      }
466    
467      optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) {      optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) {
468          return optional<int>::nothing;          if (!Parameters.count("CARD")) return optional<int>::nothing;
469    
470            // obtain information from given sound card
471            ParameterCard card(Parameters["CARD"]);
472            String pcm_name = "hw:" + card.ValueAsString();
473            snd_pcm_t* pcm_handle = NULL;
474            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
475            snd_pcm_hw_params_t* hwparams;
476            snd_pcm_hw_params_alloca(&hwparams);
477            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
478                snd_pcm_close(pcm_handle);
479                return optional<int>::nothing;
480            }
481            int dir = 0;
482            unsigned long period_size_max;
483            if (snd_pcm_hw_params_get_period_size_max(hwparams, &period_size_max, &dir) < 0) {
484                snd_pcm_close(pcm_handle);
485                return optional<int>::nothing;
486            }
487            snd_pcm_close(pcm_handle);
488            return (int) period_size_max; //FIXME: might overflow int limit
489      }      }
490    
491      std::vector<int> AudioOutputDeviceAlsa::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) {      std::vector<int> AudioOutputDeviceAlsa::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) {
492          return std::vector<int>();          return std::vector<int>();
493      }      }
494    
495      void AudioOutputDeviceAlsa::ParameterFragmentSize::OnSetValue(int i) throw (LinuxSamplerException) {      void AudioOutputDeviceAlsa::ParameterFragmentSize::OnSetValue(int i) throw (Exception) {
496          // not posssible, as parameter is fix          // not posssible, as parameter is fix
497      }      }
498    
499      String AudioOutputDeviceAlsa::ParameterFragmentSize::Name() {      String AudioOutputDeviceAlsa::ParameterFragmentSize::Name() {
500          return "fragmentsize";          return "FRAGMENTSIZE";
501      }      }
502    
503    
# Line 229  namespace LinuxSampler { Line 511  namespace LinuxSampler {
511       * @param Parameters - optional parameters       * @param Parameters - optional parameters
512       * @throws AudioOutputException  if output device cannot be opened       * @throws AudioOutputException  if output device cannot be opened
513       */       */
514      AudioOutputDeviceAlsa::AudioOutputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters), Thread(true, 1, 0) {      AudioOutputDeviceAlsa::AudioOutputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters), Thread(true, true, 1, 0) {
515          pcm_handle           = NULL;          pcm_handle           = NULL;
516          stream               = SND_PCM_STREAM_PLAYBACK;          stream               = SND_PCM_STREAM_PLAYBACK;
517          this->uiAlsaChannels = ((DeviceCreationParameterInt*)Parameters["channels"])->ValueAsInt();          this->uiAlsaChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();
518          this->uiSamplerate   = ((DeviceCreationParameterInt*)Parameters["samplerate"])->ValueAsInt();          this->uiSamplerate   = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();
519          this->FragmentSize   = ((DeviceCreationParameterInt*)Parameters["fragmentsize"])->ValueAsInt();          this->FragmentSize   = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt();
520          uint Fragments       = ((DeviceCreationParameterInt*)Parameters["fragments"])->ValueAsInt();          uint Fragments       = ((DeviceCreationParameterInt*)Parameters["FRAGMENTS"])->ValueAsInt();
521          String Card          = ((DeviceCreationParameterString*)Parameters["card"])->ValueAsString();          String Card          = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString();
522    
523          dmsg(1,("Checking if hw parameters supported...\n"));          dmsg(2,("Checking if hw parameters supported...\n"));
524          if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) {          if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) {
525              pcm_name = "hw:" + Card;              pcm_name = "hw:" + Card;
526          }          }
527          else {          else {
528              printf("Warning: your soundcard doesn't support chosen hardware parameters; ");              fprintf(stderr, "Warning: your soundcard doesn't support chosen hardware parameters; ");
529              printf("trying to compensate support lack with plughw...");              fprintf(stderr, "trying to compensate support lack with plughw...");
530              fflush(stdout);              fflush(stdout);
531              pcm_name = "plughw:" + Card;              pcm_name = "plughw:" + Card;
532          }          }
533          dmsg(1,("HW check completed.\n"));          dmsg(2,("HW check completed.\n"));
534    
535          int err;          int err;
536    
# Line 305  namespace LinuxSampler { Line 587  namespace LinuxSampler {
587    
588          /* Set number of periods. Periods used to be called fragments. */          /* Set number of periods. Periods used to be called fragments. */
589          if ((err = snd_pcm_hw_params_set_periods(pcm_handle, hwparams, Fragments, dir)) < 0) {          if ((err = snd_pcm_hw_params_set_periods(pcm_handle, hwparams, Fragments, dir)) < 0) {
590              throw AudioOutputException(String("Error setting number of periods: ") + snd_strerror(err));              throw AudioOutputException(String("Error setting number of ") + ToString(Fragments) + " periods: " + snd_strerror(err));
591          }          }
592    
593          /* Set buffer size (in frames). The resulting latency is given by */          /* Set buffer size (in frames). The resulting latency is given by */
# Line 344  namespace LinuxSampler { Line 626  namespace LinuxSampler {
626          pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize];          pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize];
627    
628          // create audio channels for this audio device to which the sampler engines can write to          // create audio channels for this audio device to which the sampler engines can write to
629          for (int i = 0; i < uiAlsaChannels; i++) this->Channels.push_back(new AudioChannel(FragmentSize));          for (int i = 0; i < uiAlsaChannels; i++) this->Channels.push_back(new AudioChannel(i, FragmentSize));
630    
631          if (((DeviceCreationParameterBool*)Parameters["active"])->ValueAsBool()) {          if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
632                  Play();                  Play();
633          }          }
634      }      }
# Line 356  namespace LinuxSampler { Line 638  namespace LinuxSampler {
638          //StopThread();  //FIXME: commented out due to a bug in thread.cpp (StopThread() doesn't return at all)          //StopThread();  //FIXME: commented out due to a bug in thread.cpp (StopThread() doesn't return at all)
639          //dmsg(0,("OK\n"));          //dmsg(0,("OK\n"));
640    
641          //FIXME: currently commented out due to segfault          snd_pcm_close(pcm_handle);
         //snd_pcm_close(pcm_handle);  
   
         // destroy all audio channels  
         for (int c = 0; c < Channels.size(); c++) delete Channels[c];  
642    
643          if (pAlsaOutputBuffer) {          if (pAlsaOutputBuffer) {
644              //FIXME: currently commented out due to segfault              //FIXME: currently commented out due to segfault
# Line 372  namespace LinuxSampler { Line 650  namespace LinuxSampler {
650       *  Checks if sound card supports the chosen parameters.       *  Checks if sound card supports the chosen parameters.
651       *       *
652       *  @returns  true if hardware supports it       *  @returns  true if hardware supports it
653         *  @throws AudioOutputException - if device cannot be accessed
654       */       */
655      bool AudioOutputDeviceAlsa::HardwareParametersSupported(String card, uint channels, int samplerate, uint numfragments, uint fragmentsize) {      bool AudioOutputDeviceAlsa::HardwareParametersSupported(String card, uint channels, int samplerate, uint numfragments, uint fragmentsize) throw (AudioOutputException) {
656          pcm_name = "hw:" + card;          pcm_name = "hw:" + card;
657          if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), stream, 0) < 0) return false;          int err;
658            if ((err = snd_pcm_open(&pcm_handle, pcm_name.c_str(), stream, SND_PCM_NONBLOCK)) < 0) {
659                throw AudioOutputException(String("Error opening PCM device ") + pcm_name + ": " + snd_strerror(err));
660            }
661          snd_pcm_hw_params_alloca(&hwparams);          snd_pcm_hw_params_alloca(&hwparams);
662          if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {          if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
663              snd_pcm_close(pcm_handle);              snd_pcm_close(pcm_handle);
# Line 428  namespace LinuxSampler { Line 710  namespace LinuxSampler {
710          StopThread();          StopThread();
711      }      }
712    
713      void AudioOutputDeviceAlsa::AcquireChannels(uint Channels) {      AudioChannel* AudioOutputDeviceAlsa::CreateChannel(uint ChannelNr) {
714          if (Channels > uiAlsaChannels) {          // just create a mix channel
715              // just create mix channel(s)          return new AudioChannel(ChannelNr, Channel(ChannelNr % uiAlsaChannels));
             for (int i = uiAlsaChannels; i < Channels; i++) {  
                 AudioChannel* pNewChannel = new AudioChannel(this->Channels[i % uiAlsaChannels]);  
                 this->Channels.push_back(pNewChannel);  
             }  
         }  
716      }      }
717    
718      uint AudioOutputDeviceAlsa::MaxSamplesPerCycle() {      uint AudioOutputDeviceAlsa::MaxSamplesPerCycle() {
# Line 447  namespace LinuxSampler { Line 724  namespace LinuxSampler {
724      }      }
725    
726      String AudioOutputDeviceAlsa::Name() {      String AudioOutputDeviceAlsa::Name() {
727          return "Alsa";          return "ALSA";
728      }      }
729    
730      String AudioOutputDeviceAlsa::Driver() {      String AudioOutputDeviceAlsa::Driver() {
# Line 459  namespace LinuxSampler { Line 736  namespace LinuxSampler {
736      }      }
737    
738      String AudioOutputDeviceAlsa::Version() {      String AudioOutputDeviceAlsa::Version() {
739         String s = "$Revision: 1.12 $";         String s = "$Revision: 1.25 $";
740         return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword         return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
741      }      }
742    
# Line 492  namespace LinuxSampler { Line 769  namespace LinuxSampler {
769                  exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
770              }              }
771          }          }
772            // just to suppress compiler warning
773            return EXIT_FAILURE;
774      }      }
775    
776      /**      /**
# Line 510  namespace LinuxSampler { Line 789  namespace LinuxSampler {
789      }      }
790    
791  } // namespace LinuxSampler  } // namespace LinuxSampler
   

Legend:
Removed from v.214  
changed lines
  Added in v.1599

  ViewVC Help
Powered by ViewVC