/[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 200 by schoenebeck, Tue Jul 13 22:04:16 2004 UTC revision 1049 by schoenebeck, Wed Feb 28 06:53:42 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 20  Line 21 
21   *   MA  02111-1307  USA                                                   *   *   MA  02111-1307  USA                                                   *
22   ***************************************************************************/   ***************************************************************************/
23    
 #include "../InputOutputDevice.h"  
24  #include "AudioOutputDeviceAlsa.h"  #include "AudioOutputDeviceAlsa.h"
25  #include "AudioOutputDeviceFactory.h"  #include "AudioOutputDeviceFactory.h"
26    
27  namespace LinuxSampler {  namespace LinuxSampler {
28    
29      REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDeviceAlsa);  // *************** ParameterCard ***************
30    // *
31    
32      /* Common parameters for now they'll have to be registered here. */      AudioOutputDeviceAlsa::ParameterCard::ParameterCard() : DeviceCreationParameterString() {
33      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterActive);          InitWithDefault(); // use default card
34      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterSampleRate);      }
35      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterChannels);  
36        AudioOutputDeviceAlsa::ParameterCard::ParameterCard(String s) throw (Exception) : DeviceCreationParameterString(s) {
37      /* Driver specific parameters */      }
38      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterCard);  
39      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragments);      String AudioOutputDeviceAlsa::ParameterCard::Description() {
40      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragmentSize);          return "Sound card to be used";
41        }
42    
43        bool AudioOutputDeviceAlsa::ParameterCard::Fix() {
44            return true;
45        }
46    
47        bool AudioOutputDeviceAlsa::ParameterCard::Mandatory() {
48            return false;
49        }
50    
51        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::ParameterCard::DependsAsParameters() {
52            return std::map<String,DeviceCreationParameter*>(); // no dependencies
53        }
54    
55        optional<String> AudioOutputDeviceAlsa::ParameterCard::DefaultAsString(std::map<String,String> Parameters) {
56            std::vector<String> cards = PossibilitiesAsString(Parameters);
57            if (cards.empty()) throw Exception("AudioOutputDeviceAlsa: Can't find any card");
58            return cards[0]; // first card by default
59        }
60    
61        std::vector<String> AudioOutputDeviceAlsa::ParameterCard::PossibilitiesAsString(std::map<String,String> Parameters) {
62            int err;
63            std::vector<String> CardNames;
64    
65            // iterate through all cards
66            int card_index = -1;
67            while (snd_card_next(&card_index) >= 0 && card_index >= 0) {
68                String hw_name = "hw:" + ToString(card_index);
69                snd_ctl_t* hCardCtrl;
70                if ((err = snd_ctl_open(&hCardCtrl, hw_name.c_str(), 0)) < 0) {
71                    std::cerr << "AudioOutputDeviceAlsa: Cannot open sound control for card " << card_index << " - " << snd_strerror(err) << std::endl;
72                    continue;
73                }
74    
75                // iterate through all devices of that card
76                int device_index = -1;
77                while (!snd_ctl_pcm_next_device(hCardCtrl, &device_index) && device_index >= 0) {
78                    String name = ToString(card_index) + "," + ToString(device_index);
79                    //dmsg(1,("[possibility:%s]", name.c_str()));
80                    CardNames.push_back(name);
81                }
82    
83                snd_ctl_close(hCardCtrl);
84            }
85    
86            return CardNames;
87        }
88    
89        void AudioOutputDeviceAlsa::ParameterCard::OnSetValue(String s) throw (Exception) {
90            // not posssible, as parameter is fix
91        }
92    
93        String AudioOutputDeviceAlsa::ParameterCard::Name() {
94            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            if (!Parameters.count("CARD")) return optional<int>::nothing;
229    
230            // obtain information from given sound card
231            ParameterCard card(Parameters["CARD"]);
232            String pcm_name = "hw:" + card.ValueAsString();
233            snd_pcm_t* pcm_handle = NULL;
234            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
235            snd_pcm_hw_params_t* hwparams;
236            snd_pcm_hw_params_alloca(&hwparams);
237            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
238                snd_pcm_close(pcm_handle);
239                return optional<int>::nothing;
240            }
241            uint channels;
242            if (snd_pcm_hw_params_get_channels_min(hwparams, &channels) < 0) {
243                snd_pcm_close(pcm_handle);
244                return optional<int>::nothing;
245            }
246            snd_pcm_close(pcm_handle);
247            return channels;
248        }
249    
250        optional<int> AudioOutputDeviceAlsa::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {
251            if (!Parameters.count("CARD")) return optional<int>::nothing;
252    
253            // obtain information from given sound card
254            String pcm_name       = "hw:" + Parameters["CARD"];
255            snd_pcm_t* pcm_handle = NULL;
256            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
257            snd_pcm_hw_params_t* hwparams;
258            snd_pcm_hw_params_alloca(&hwparams);
259            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
260                snd_pcm_close(pcm_handle);
261                return optional<int>::nothing;
262            }
263            uint channels;
264            if (snd_pcm_hw_params_get_channels_max(hwparams, &channels) < 0) {
265                snd_pcm_close(pcm_handle);
266                return optional<int>::nothing;
267            }
268            snd_pcm_close(pcm_handle);
269            return channels;
270        }
271    
272    
273    
274    // *************** ParameterFragments ***************
275    // *
276    
277        AudioOutputDeviceAlsa::ParameterFragments::ParameterFragments() : DeviceCreationParameterInt() {
278            InitWithDefault();
279        }
280    
281        AudioOutputDeviceAlsa::ParameterFragments::ParameterFragments(String s) throw (Exception) : DeviceCreationParameterInt(s) {
282        }
283    
284        String AudioOutputDeviceAlsa::ParameterFragments::Description() {
285            return "Number of buffer fragments";
286        }
287    
288        bool AudioOutputDeviceAlsa::ParameterFragments::Fix() {
289            return true;
290        }
291    
292        bool AudioOutputDeviceAlsa::ParameterFragments::Mandatory() {
293            return false;
294        }
295    
296        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::ParameterFragments::DependsAsParameters() {
297            static ParameterCard card;
298            std::map<String,DeviceCreationParameter*> dependencies;
299            dependencies[card.Name()] = &card;
300            return dependencies;
301        }
302    
303        optional<int> AudioOutputDeviceAlsa::ParameterFragments::DefaultAsInt(std::map<String,String> Parameters) {
304            if (!Parameters.count("CARD")) return optional<int>::nothing;
305    
306            // obtain information from given sound card
307            ParameterCard card(Parameters["CARD"]);
308            String pcm_name = "hw:" + card.ValueAsString();
309            snd_pcm_t* pcm_handle = NULL;
310            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
311            snd_pcm_hw_params_t* hwparams;
312            snd_pcm_hw_params_alloca(&hwparams);
313            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
314                snd_pcm_close(pcm_handle);
315                return optional<int>::nothing;
316            }
317            uint segs = 2;
318            if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &segs, NULL) < 0) {
319                snd_pcm_close(pcm_handle);
320                return optional<int>::nothing;
321            }
322            snd_pcm_close(pcm_handle);
323            return segs;
324        }
325    
326        optional<int> AudioOutputDeviceAlsa::ParameterFragments::RangeMinAsInt(std::map<String,String> Parameters) {
327            if (!Parameters.count("CARD")) return optional<int>::nothing;
328    
329            // obtain information from given sound card
330            ParameterCard card(Parameters["CARD"]);
331            String pcm_name = "hw:" + card.ValueAsString();
332            snd_pcm_t* pcm_handle = NULL;
333            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
334            snd_pcm_hw_params_t* hwparams;
335            snd_pcm_hw_params_alloca(&hwparams);
336            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
337                snd_pcm_close(pcm_handle);
338                return optional<int>::nothing;
339            }
340            int dir = 0;
341            uint periods_min;
342            if (snd_pcm_hw_params_get_periods_min(hwparams, &periods_min, &dir) < 0) {
343                snd_pcm_close(pcm_handle);
344                return optional<int>::nothing;
345            }
346            snd_pcm_close(pcm_handle);
347            return (int) periods_min;
348        }
349    
350        optional<int> AudioOutputDeviceAlsa::ParameterFragments::RangeMaxAsInt(std::map<String,String> Parameters) {
351            if (!Parameters.count("CARD")) return optional<int>::nothing;
352    
353            // obtain information from given sound card
354            ParameterCard card(Parameters["CARD"]);
355            String pcm_name = "hw:" + card.ValueAsString();
356            snd_pcm_t* pcm_handle = NULL;
357            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
358            snd_pcm_hw_params_t* hwparams;
359            snd_pcm_hw_params_alloca(&hwparams);
360            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
361                snd_pcm_close(pcm_handle);
362                return optional<int>::nothing;
363            }
364            int dir = 0;
365            uint periods_max;
366            if (snd_pcm_hw_params_get_periods_max(hwparams, &periods_max, &dir) < 0) {
367                snd_pcm_close(pcm_handle);
368                return optional<int>::nothing;
369            }
370            snd_pcm_close(pcm_handle);
371            return (int) periods_max;
372        }
373    
374        std::vector<int> AudioOutputDeviceAlsa::ParameterFragments::PossibilitiesAsInt(std::map<String,String> Parameters) {
375            return std::vector<int>();
376        }
377    
378        void AudioOutputDeviceAlsa::ParameterFragments::OnSetValue(int i) throw (Exception) {
379            // not posssible, as parameter is fix
380        }
381    
382        String AudioOutputDeviceAlsa::ParameterFragments::Name() {
383            return "FRAGMENTS";
384        }
385    
386    
387    
388    // *************** ParameterFragmentSize ***************
389    // *
390    
391        AudioOutputDeviceAlsa::ParameterFragmentSize::ParameterFragmentSize() : DeviceCreationParameterInt() {
392            InitWithDefault();
393        }
394    
395        AudioOutputDeviceAlsa::ParameterFragmentSize::ParameterFragmentSize(String s) throw (Exception) : DeviceCreationParameterInt(s) {
396        }
397    
398        String AudioOutputDeviceAlsa::ParameterFragmentSize::Description() {
399            return "Size of each buffer fragment";
400        }
401    
402        bool AudioOutputDeviceAlsa::ParameterFragmentSize::Fix() {
403            return true;
404        }
405    
406        bool AudioOutputDeviceAlsa::ParameterFragmentSize::Mandatory() {
407            return false;
408        }
409    
410        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::ParameterFragmentSize::DependsAsParameters() {
411            static ParameterCard card;
412            std::map<String,DeviceCreationParameter*> dependencies;
413            dependencies[card.Name()] = &card;
414            return dependencies;
415        }
416    
417        optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) {
418            if (!Parameters.count("CARD")) return optional<int>::nothing;
419    
420            // obtain information from given sound card
421            ParameterCard card(Parameters["CARD"]);
422            String pcm_name = "hw:" + card.ValueAsString();
423            snd_pcm_t* pcm_handle = NULL;
424            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
425            snd_pcm_hw_params_t* hwparams;
426            snd_pcm_hw_params_alloca(&hwparams);
427            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
428                snd_pcm_close(pcm_handle);
429                return optional<int>::nothing;
430            }
431            snd_pcm_uframes_t size = 128;
432            if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &size, NULL) < 0) {
433                snd_pcm_close(pcm_handle);
434                return optional<int>::nothing;
435            }
436            snd_pcm_close(pcm_handle);
437            return size;
438        }
439    
440        optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) {
441            if (!Parameters.count("CARD")) return optional<int>::nothing;
442    
443            // obtain information from given sound card
444            ParameterCard card(Parameters["CARD"]);
445            String pcm_name = "hw:" + card.ValueAsString();
446            snd_pcm_t* pcm_handle = NULL;
447            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
448            snd_pcm_hw_params_t* hwparams;
449            snd_pcm_hw_params_alloca(&hwparams);
450            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
451                snd_pcm_close(pcm_handle);
452                return optional<int>::nothing;
453            }
454            int dir = 0;
455            unsigned long period_size_min;
456            if (snd_pcm_hw_params_get_period_size_min(hwparams, &period_size_min, &dir) < 0) {
457                snd_pcm_close(pcm_handle);
458                return optional<int>::nothing;
459            }
460            snd_pcm_close(pcm_handle);
461            return (int) period_size_min;
462        }
463    
464        optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) {
465            if (!Parameters.count("CARD")) return optional<int>::nothing;
466    
467            // obtain information from given sound card
468            ParameterCard card(Parameters["CARD"]);
469            String pcm_name = "hw:" + card.ValueAsString();
470            snd_pcm_t* pcm_handle = NULL;
471            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return optional<int>::nothing;
472            snd_pcm_hw_params_t* hwparams;
473            snd_pcm_hw_params_alloca(&hwparams);
474            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
475                snd_pcm_close(pcm_handle);
476                return optional<int>::nothing;
477            }
478            int dir = 0;
479            unsigned long period_size_max;
480            if (snd_pcm_hw_params_get_period_size_max(hwparams, &period_size_max, &dir) < 0) {
481                snd_pcm_close(pcm_handle);
482                return optional<int>::nothing;
483            }
484            snd_pcm_close(pcm_handle);
485            return (int) period_size_max; //FIXME: might overflow int limit
486        }
487    
488        std::vector<int> AudioOutputDeviceAlsa::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) {
489            return std::vector<int>();
490        }
491    
492        void AudioOutputDeviceAlsa::ParameterFragmentSize::OnSetValue(int i) throw (Exception) {
493            // not posssible, as parameter is fix
494        }
495    
496        String AudioOutputDeviceAlsa::ParameterFragmentSize::Name() {
497            return "FRAGMENTSIZE";
498        }
499    
500    
501    
502    // *************** AudioOutputDeviceAlsa ***************
503    // *
504    
505      /**      /**
506       * Create and initialize Alsa audio output device with given parameters.       * Create and initialize Alsa audio output device with given parameters.
# Line 44  namespace LinuxSampler { Line 508  namespace LinuxSampler {
508       * @param Parameters - optional parameters       * @param Parameters - optional parameters
509       * @throws AudioOutputException  if output device cannot be opened       * @throws AudioOutputException  if output device cannot be opened
510       */       */
511      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) {
512          pcm_handle           = NULL;          pcm_handle           = NULL;
513          stream               = SND_PCM_STREAM_PLAYBACK;          stream               = SND_PCM_STREAM_PLAYBACK;
514          this->uiAlsaChannels = ((DeviceCreationParameterInt*)Parameters["channels"])->ValueAsInt();          this->uiAlsaChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();
515          this->uiSamplerate   = ((DeviceCreationParameterInt*)Parameters["samplerate"])->ValueAsInt();          this->uiSamplerate   = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();
516          this->FragmentSize   = ((DeviceCreationParameterInt*)Parameters["fragmentsize"])->ValueAsInt();          this->FragmentSize   = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt();
517          uint Fragments       = ((DeviceCreationParameterInt*)Parameters["fragments"])->ValueAsInt();          uint Fragments       = ((DeviceCreationParameterInt*)Parameters["FRAGMENTS"])->ValueAsInt();
518          String Card          = Parameters["card"]->Value();          String Card          = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString();
519    
520          dmsg(1,("Checking if hw parameters supported...\n"));          dmsg(2,("Checking if hw parameters supported...\n"));
521          if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) {          if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) {
522              pcm_name = "hw:" + Card;              pcm_name = "hw:" + Card;
523          }          }
524          else {          else {
525              printf("Warning: your soundcard doesn't support chosen hardware parameters; ");              fprintf(stderr, "Warning: your soundcard doesn't support chosen hardware parameters; ");
526              printf("trying to compensate support lack with plughw...");              fprintf(stderr, "trying to compensate support lack with plughw...");
527              fflush(stdout);              fflush(stdout);
528              pcm_name = "plughw:" + Card;              pcm_name = "plughw:" + Card;
529          }          }
530          dmsg(1,("HW check completed.\n"));          dmsg(2,("HW check completed.\n"));
531    
532          int err;          int err;
533    
# Line 120  namespace LinuxSampler { Line 584  namespace LinuxSampler {
584    
585          /* Set number of periods. Periods used to be called fragments. */          /* Set number of periods. Periods used to be called fragments. */
586          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) {
587              throw AudioOutputException(String("Error setting number of periods: ") + snd_strerror(err));              throw AudioOutputException(String("Error setting number of ") + ToString(Fragments) + " periods: " + snd_strerror(err));
588          }          }
589    
590          /* Set buffer size (in frames). The resulting latency is given by */          /* Set buffer size (in frames). The resulting latency is given by */
# Line 159  namespace LinuxSampler { Line 623  namespace LinuxSampler {
623          pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize];          pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize];
624    
625          // 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
626          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));
627    
628          if (((DeviceCreationParameterBool*)Parameters["active"])->ValueAsBool()) {          if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
629                  Play();                  Play();
630          }          }
631      }      }
# Line 174  namespace LinuxSampler { Line 638  namespace LinuxSampler {
638          //FIXME: currently commented out due to segfault          //FIXME: currently commented out due to segfault
639          //snd_pcm_close(pcm_handle);          //snd_pcm_close(pcm_handle);
640    
         // destroy all audio channels  
         for (int c = 0; c < Channels.size(); c++) delete Channels[c];  
   
641          if (pAlsaOutputBuffer) {          if (pAlsaOutputBuffer) {
642              //FIXME: currently commented out due to segfault              //FIXME: currently commented out due to segfault
643              //delete[] pOutputBuffer;              //delete[] pOutputBuffer;
# Line 187  namespace LinuxSampler { Line 648  namespace LinuxSampler {
648       *  Checks if sound card supports the chosen parameters.       *  Checks if sound card supports the chosen parameters.
649       *       *
650       *  @returns  true if hardware supports it       *  @returns  true if hardware supports it
651         *  @throws AudioOutputException - if device cannot be accessed
652       */       */
653      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) {
654          pcm_name = "hw:" + card;          pcm_name = "hw:" + card;
655          if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), stream, 0) < 0) return false;          int err;
656            if ((err = snd_pcm_open(&pcm_handle, pcm_name.c_str(), stream, SND_PCM_NONBLOCK)) < 0) {
657                throw AudioOutputException(String("Error opening PCM device ") + pcm_name + ": " + snd_strerror(err));
658            }
659          snd_pcm_hw_params_alloca(&hwparams);          snd_pcm_hw_params_alloca(&hwparams);
660          if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {          if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
661              snd_pcm_close(pcm_handle);              snd_pcm_close(pcm_handle);
# Line 243  namespace LinuxSampler { Line 708  namespace LinuxSampler {
708          StopThread();          StopThread();
709      }      }
710    
711      void AudioOutputDeviceAlsa::AcquireChannels(uint Channels) {      AudioChannel* AudioOutputDeviceAlsa::CreateChannel(uint ChannelNr) {
712          if (Channels > uiAlsaChannels) {          // just create a mix channel
713              // 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);  
             }  
         }  
714      }      }
715    
716      uint AudioOutputDeviceAlsa::MaxSamplesPerCycle() {      uint AudioOutputDeviceAlsa::MaxSamplesPerCycle() {
# Line 262  namespace LinuxSampler { Line 722  namespace LinuxSampler {
722      }      }
723    
724      String AudioOutputDeviceAlsa::Name() {      String AudioOutputDeviceAlsa::Name() {
725          return "Alsa";          return "ALSA";
726      }      }
727    
728      String AudioOutputDeviceAlsa::Driver() {      String AudioOutputDeviceAlsa::Driver() {
# Line 274  namespace LinuxSampler { Line 734  namespace LinuxSampler {
734      }      }
735    
736      String AudioOutputDeviceAlsa::Version() {      String AudioOutputDeviceAlsa::Version() {
737         String s = "$Revision: 1.9 $";         String s = "$Revision: 1.22 $";
738         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
739      }      }
740    
# Line 325  namespace LinuxSampler { Line 785  namespace LinuxSampler {
785      }      }
786    
787  } // namespace LinuxSampler  } // namespace LinuxSampler
   

Legend:
Removed from v.200  
changed lines
  Added in v.1049

  ViewVC Help
Powered by ViewVC