/[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 208 by schoenebeck, Thu Jul 15 22:20:28 2004 UTC revision 227 by schoenebeck, Thu Aug 26 22:05:44 2004 UTC
# Line 37  namespace LinuxSampler { Line 37  namespace LinuxSampler {
37      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragments);      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragments);
38      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragmentSize);      REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragmentSize);
39    
40    
41    
42    // *************** ParameterCard ***************
43    // *
44    
45        AudioOutputDeviceAlsa::ParameterCard::ParameterCard() : DeviceCreationParameterString() {
46            InitWithDefault(); // use default card
47        }
48    
49        AudioOutputDeviceAlsa::ParameterCard::ParameterCard(String s) throw (LinuxSamplerException) : DeviceCreationParameterString(s) {
50        }
51    
52        String AudioOutputDeviceAlsa::ParameterCard::Description() {
53            return "Sound card to be used";
54        }
55    
56        bool AudioOutputDeviceAlsa::ParameterCard::Fix() {
57            return true;
58        }
59    
60        bool AudioOutputDeviceAlsa::ParameterCard::Mandatory() {
61            return false;
62        }
63    
64        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::ParameterCard::DependsAsParameters() {
65            return std::map<String,DeviceCreationParameter*>(); // no dependencies
66        }
67    
68        optional<String> AudioOutputDeviceAlsa::ParameterCard::DefaultAsString(std::map<String,String> Parameters) {
69            std::vector<String> cards = PossibilitiesAsString(Parameters);
70            if (cards.empty()) throw LinuxSamplerException("AudioOutputDeviceAlsa: Can't find any card");
71            return cards[0]; // first card by default
72        }
73    
74        std::vector<String> AudioOutputDeviceAlsa::ParameterCard::PossibilitiesAsString(std::map<String,String> Parameters) {
75            int err;
76            std::vector<String> CardNames;
77    
78            // iterate through all cards
79            int card_index = -1;
80            while (snd_card_next(&card_index) >= 0 && card_index >= 0) {
81                String hw_name = "hw:" + ToString(card_index);
82                snd_ctl_t* hCardCtrl;
83                if ((err = snd_ctl_open(&hCardCtrl, hw_name.c_str(), 0)) < 0) {
84                    std::cerr << "AudioOutputDeviceAlsa: Cannot open sound control for card " << card_index << " - " << snd_strerror(err) << std::endl;
85                    continue;
86                }
87    
88                // iterate through all devices of that card
89                int device_index = -1;
90                while (!snd_ctl_pcm_next_device(hCardCtrl, &device_index) && device_index >= 0) {
91                    String name = ToString(card_index) + "," + ToString(device_index);
92                    //dmsg(1,("[possibility:%s]", name.c_str()));
93                    CardNames.push_back(name);
94                }
95    
96                snd_ctl_close(hCardCtrl);
97            }
98    
99            return CardNames;
100        }
101    
102        void AudioOutputDeviceAlsa::ParameterCard::OnSetValue(String s) throw (LinuxSamplerException) {
103            // not posssible, as parameter is fix
104        }
105    
106        String AudioOutputDeviceAlsa::ParameterCard::Name() {
107            return "CARD";
108        }
109    
110    
111    
112    // *************** ParameterFragments ***************
113    // *
114    
115        AudioOutputDeviceAlsa::ParameterFragments::ParameterFragments() : DeviceCreationParameterInt() {
116            InitWithDefault();
117        }
118    
119        AudioOutputDeviceAlsa::ParameterFragments::ParameterFragments(String s) throw (LinuxSamplerException) : DeviceCreationParameterInt(s) {
120        }
121    
122        String AudioOutputDeviceAlsa::ParameterFragments::Description() {
123            return "Number of buffer fragments";
124        }
125    
126        bool AudioOutputDeviceAlsa::ParameterFragments::Fix() {
127            return true;
128        }
129    
130        bool AudioOutputDeviceAlsa::ParameterFragments::Mandatory() {
131            return false;
132        }
133    
134        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::ParameterFragments::DependsAsParameters() {
135            static ParameterCard card;
136            std::map<String,DeviceCreationParameter*> dependencies;
137            dependencies[card.Name()] = &card;
138            return dependencies;
139        }
140    
141        optional<int> AudioOutputDeviceAlsa::ParameterFragments::DefaultAsInt(std::map<String,String> Parameters) {
142            return 2; // until done
143        }
144    
145        optional<int> AudioOutputDeviceAlsa::ParameterFragments::RangeMinAsInt(std::map<String,String> Parameters) {
146            if (!Parameters.count("CARD")) return optional<int>::nothing;
147    
148            // obtain information from given sound card
149            String pcm_name       = "hw:" + Parameters["CARD"];
150            snd_pcm_t* pcm_handle = NULL;
151            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, 0) < 0) return optional<int>::nothing;
152            snd_pcm_hw_params_t* hwparams;
153            snd_pcm_hw_params_alloca(&hwparams);
154            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
155                snd_pcm_close(pcm_handle);
156                return optional<int>::nothing;
157            }
158            int dir = 0;
159            uint periods_min;
160            if (snd_pcm_hw_params_get_periods_min(hwparams, &periods_min, &dir) < 0) {
161                snd_pcm_close(pcm_handle);
162                return optional<int>::nothing;
163            }
164            snd_pcm_close(pcm_handle);
165            return (int) periods_min;
166        }
167    
168        optional<int> AudioOutputDeviceAlsa::ParameterFragments::RangeMaxAsInt(std::map<String,String> Parameters) {
169            if (!Parameters.count("CARD")) return optional<int>::nothing;
170    
171            // obtain information from given sound card
172            String pcm_name       = "hw:" + Parameters["CARD"];
173            snd_pcm_t* pcm_handle = NULL;
174            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, 0) < 0) return optional<int>::nothing;
175            snd_pcm_hw_params_t* hwparams;
176            snd_pcm_hw_params_alloca(&hwparams);
177            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
178                snd_pcm_close(pcm_handle);
179                return optional<int>::nothing;
180            }
181            int dir = 0;
182            uint periods_max;
183            if (snd_pcm_hw_params_get_periods_max(hwparams, &periods_max, &dir) < 0) {
184                snd_pcm_close(pcm_handle);
185                return optional<int>::nothing;
186            }
187            snd_pcm_close(pcm_handle);
188            return (int) periods_max;
189        }
190    
191        std::vector<int> AudioOutputDeviceAlsa::ParameterFragments::PossibilitiesAsInt(std::map<String,String> Parameters) {
192            return std::vector<int>();
193        }
194    
195        void AudioOutputDeviceAlsa::ParameterFragments::OnSetValue(int i) throw (LinuxSamplerException) {
196            // not posssible, as parameter is fix
197        }
198    
199        String AudioOutputDeviceAlsa::ParameterFragments::Name() {
200            return "FRAGMENTS";
201        }
202    
203    
204    
205    // *************** ParameterFragmentSize ***************
206    // *
207    
208        AudioOutputDeviceAlsa::ParameterFragmentSize::ParameterFragmentSize() : DeviceCreationParameterInt() {
209            InitWithDefault();
210        }
211    
212        AudioOutputDeviceAlsa::ParameterFragmentSize::ParameterFragmentSize(String s) throw (LinuxSamplerException) : DeviceCreationParameterInt(s) {
213        }
214    
215        String AudioOutputDeviceAlsa::ParameterFragmentSize::Description() {
216            return "Size of each buffer fragment";
217        }
218    
219        bool AudioOutputDeviceAlsa::ParameterFragmentSize::Fix() {
220            return true;
221        }
222    
223        bool AudioOutputDeviceAlsa::ParameterFragmentSize::Mandatory() {
224            return false;
225        }
226    
227        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::ParameterFragmentSize::DependsAsParameters() {
228            static ParameterCard card;
229            std::map<String,DeviceCreationParameter*> dependencies;
230            dependencies[card.Name()] = &card;
231            return dependencies;
232        }
233    
234        optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) {
235            return 128; // until done
236        }
237    
238        optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) {
239            if (!Parameters.count("CARD")) return optional<int>::nothing;
240    
241            // obtain information from given sound card
242            String pcm_name       = "hw:" + Parameters["CARD"];
243            snd_pcm_t* pcm_handle = NULL;
244            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, 0) < 0) return optional<int>::nothing;
245            snd_pcm_hw_params_t* hwparams;
246            snd_pcm_hw_params_alloca(&hwparams);
247            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
248                snd_pcm_close(pcm_handle);
249                return optional<int>::nothing;
250            }
251            int dir = 0;
252            unsigned long period_size_min;
253            if (snd_pcm_hw_params_get_period_size_min(hwparams, &period_size_min, &dir) < 0) {
254                snd_pcm_close(pcm_handle);
255                return optional<int>::nothing;
256            }
257            snd_pcm_close(pcm_handle);
258            return (int) period_size_min;
259        }
260    
261        optional<int> AudioOutputDeviceAlsa::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) {
262            if (!Parameters.count("CARD")) return optional<int>::nothing;
263    
264            // obtain information from given sound card
265            String pcm_name       = "hw:" + Parameters["CARD"];
266            snd_pcm_t* pcm_handle = NULL;
267            if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), SND_PCM_STREAM_PLAYBACK, 0) < 0) return optional<int>::nothing;
268            snd_pcm_hw_params_t* hwparams;
269            snd_pcm_hw_params_alloca(&hwparams);
270            if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
271                snd_pcm_close(pcm_handle);
272                return optional<int>::nothing;
273            }
274            int dir = 0;
275            unsigned long period_size_max;
276            if (snd_pcm_hw_params_get_period_size_max(hwparams, &period_size_max, &dir) < 0) {
277                snd_pcm_close(pcm_handle);
278                return optional<int>::nothing;
279            }
280            snd_pcm_close(pcm_handle);
281            return (int) period_size_max; //FIXME: might overflow int limit
282        }
283    
284        std::vector<int> AudioOutputDeviceAlsa::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) {
285            return std::vector<int>();
286        }
287    
288        void AudioOutputDeviceAlsa::ParameterFragmentSize::OnSetValue(int i) throw (LinuxSamplerException) {
289            // not posssible, as parameter is fix
290        }
291    
292        String AudioOutputDeviceAlsa::ParameterFragmentSize::Name() {
293            return "FRAGMENTSIZE";
294        }
295    
296    
297    
298    // *************** AudioOutputDeviceAlsa ***************
299    // *
300    
301      /**      /**
302       * Create and initialize Alsa audio output device with given parameters.       * Create and initialize Alsa audio output device with given parameters.
303       *       *
# Line 46  namespace LinuxSampler { Line 307  namespace LinuxSampler {
307      AudioOutputDeviceAlsa::AudioOutputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters), Thread(true, 1, 0) {      AudioOutputDeviceAlsa::AudioOutputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters), Thread(true, 1, 0) {
308          pcm_handle           = NULL;          pcm_handle           = NULL;
309          stream               = SND_PCM_STREAM_PLAYBACK;          stream               = SND_PCM_STREAM_PLAYBACK;
310          this->uiAlsaChannels = ((DeviceCreationParameterInt*)Parameters["channels"])->ValueAsInt();          this->uiAlsaChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();
311          this->uiSamplerate   = ((DeviceCreationParameterInt*)Parameters["samplerate"])->ValueAsInt();          this->uiSamplerate   = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();
312          this->FragmentSize   = ((DeviceCreationParameterInt*)Parameters["fragmentsize"])->ValueAsInt();          this->FragmentSize   = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt();
313          uint Fragments       = ((DeviceCreationParameterInt*)Parameters["fragments"])->ValueAsInt();          uint Fragments       = ((DeviceCreationParameterInt*)Parameters["FRAGMENTS"])->ValueAsInt();
314          String Card          = Parameters["card"]->Value();          String Card          = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString();
315    
316          dmsg(1,("Checking if hw parameters supported...\n"));          dmsg(1,("Checking if hw parameters supported...\n"));
317          if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) {          if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) {
# Line 158  namespace LinuxSampler { Line 419  namespace LinuxSampler {
419          pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize];          pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize];
420    
421          // 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
422          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));
423    
424          if (((DeviceCreationParameterBool*)Parameters["active"])->ValueAsBool()) {          if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
425                  Play();                  Play();
426          }          }
427      }      }
# Line 173  namespace LinuxSampler { Line 434  namespace LinuxSampler {
434          //FIXME: currently commented out due to segfault          //FIXME: currently commented out due to segfault
435          //snd_pcm_close(pcm_handle);          //snd_pcm_close(pcm_handle);
436    
         // destroy all audio channels  
         for (int c = 0; c < Channels.size(); c++) delete Channels[c];  
   
437          if (pAlsaOutputBuffer) {          if (pAlsaOutputBuffer) {
438              //FIXME: currently commented out due to segfault              //FIXME: currently commented out due to segfault
439              //delete[] pOutputBuffer;              //delete[] pOutputBuffer;
# Line 242  namespace LinuxSampler { Line 500  namespace LinuxSampler {
500          StopThread();          StopThread();
501      }      }
502    
503      void AudioOutputDeviceAlsa::AcquireChannels(uint Channels) {      AudioChannel* AudioOutputDeviceAlsa::CreateChannel(uint ChannelNr) {
504          if (Channels > uiAlsaChannels) {          // just create a mix channel
505              // 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);  
             }  
         }  
506      }      }
507    
508      uint AudioOutputDeviceAlsa::MaxSamplesPerCycle() {      uint AudioOutputDeviceAlsa::MaxSamplesPerCycle() {
# Line 261  namespace LinuxSampler { Line 514  namespace LinuxSampler {
514      }      }
515    
516      String AudioOutputDeviceAlsa::Name() {      String AudioOutputDeviceAlsa::Name() {
517          return "Alsa";          return "ALSA";
518      }      }
519    
520      String AudioOutputDeviceAlsa::Driver() {      String AudioOutputDeviceAlsa::Driver() {
# Line 273  namespace LinuxSampler { Line 526  namespace LinuxSampler {
526      }      }
527    
528      String AudioOutputDeviceAlsa::Version() {      String AudioOutputDeviceAlsa::Version() {
529         String s = "$Revision: 1.10 $";         String s = "$Revision: 1.15 $";
530         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
531      }      }
532    
# Line 324  namespace LinuxSampler { Line 577  namespace LinuxSampler {
577      }      }
578    
579  } // namespace LinuxSampler  } // namespace LinuxSampler
   

Legend:
Removed from v.208  
changed lines
  Added in v.227

  ViewVC Help
Powered by ViewVC