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

Diff of /linuxsampler/trunk/src/audiodriver/AudioOutputDeviceAlsa.cpp

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

revision 122 by schoenebeck, Thu May 6 20:06:20 2004 UTC revision 123 by schoenebeck, Mon Jun 14 19:33:16 2004 UTC
# Line 21  Line 21 
21   ***************************************************************************/   ***************************************************************************/
22    
23  #include "AudioOutputDeviceAlsa.h"  #include "AudioOutputDeviceAlsa.h"
24    #include "AudioOutputDeviceFactory.h"
25    
26  namespace LinuxSampler {  namespace LinuxSampler {
27    
28        REGISTER_AUDIO_OUTPUT_DRIVER("ALSA",AudioOutputDeviceAlsa);
29    
30      /**      /**
31       * Open and initialize Alsa output device with given parameters.       * Create and initialize Alsa audio output device with given parameters.
32       *       *
33       * @param Channels     - number of audio channels       * @param Parameters - optional parameters
      * @param Fragments    - number of audio fragments  
      * @param FragmentSize - size of each fragment (in sample points)  
      * @param Card         - Alsa soundcard ID (optional)  
34       * @throws AudioOutputException  if output device cannot be opened       * @throws AudioOutputException  if output device cannot be opened
35       */       */
36      AudioOutputDeviceAlsa::AudioOutputDeviceAlsa(uint Channels, uint Samplerate, uint Fragments, uint FragmentSize, String Card) : AudioOutputDevice(AudioOutputDevice::type_alsa), Thread(true, 1, 0) {      AudioOutputDeviceAlsa::AudioOutputDeviceAlsa(std::map<String,String> Parameters) : AudioOutputDevice(CreateParameters(Parameters)), Thread(true, 1, 0) {
37          pcm_handle           = NULL;          pcm_handle           = NULL;
38          stream               = SND_PCM_STREAM_PLAYBACK;          stream               = SND_PCM_STREAM_PLAYBACK;
39          this->uiAlsaChannels = Channels;          this->uiAlsaChannels = ((DeviceCreationParameterInt*)this->Parameters["CHANNELS"])->ValueAsInt();
40          this->uiSamplerate   = Samplerate;          this->uiSamplerate   = ((DeviceCreationParameterInt*)this->Parameters["SAMPLERATE"])->ValueAsInt();
41          this->FragmentSize   = FragmentSize;          this->FragmentSize   = ((DeviceCreationParameterInt*)this->Parameters["FRAGMENTSIZE"])->ValueAsInt();
42            uint Fragments       = ((DeviceCreationParameterInt*)this->Parameters["FRAGMENTS"])->ValueAsInt();
43            String Card          = this->Parameters["CARD"]->Value();
44    
45          if (HardwareParametersSupported(Channels, Samplerate, Fragments, FragmentSize)) {          dmsg(1,("Checking if hw parameters supported...\n"));
46            if (HardwareParametersSupported(Card, uiAlsaChannels, uiSamplerate, Fragments, FragmentSize)) {
47              pcm_name = "hw:" + Card;              pcm_name = "hw:" + Card;
48          }          }
49          else {          else {
# Line 49  namespace LinuxSampler { Line 52  namespace LinuxSampler {
52              fflush(stdout);              fflush(stdout);
53              pcm_name = "plughw:" + Card;              pcm_name = "plughw:" + Card;
54          }          }
55            dmsg(1,("HW check completed.\n"));
56    
57          int err;          int err;
58    
# Line 91  namespace LinuxSampler { Line 95  namespace LinuxSampler {
95          /* Set sample rate. If the exact rate is not supported */          /* Set sample rate. If the exact rate is not supported */
96          /* by the hardware, use nearest possible rate.         */          /* by the hardware, use nearest possible rate.         */
97          #if ALSA_MAJOR > 0          #if ALSA_MAJOR > 0
98          if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &Samplerate, &dir)) < 0)          if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &uiSamplerate, &dir)) < 0)
99          #else          #else
100          if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, Samplerate, &dir)) < 0)          if((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, uiSamplerate, &dir)) < 0)
101          #endif          #endif
102          {          {
103              throw AudioOutputException(String("Error setting sample rate: ") + snd_strerror(err));              throw AudioOutputException(String("Error setting sample rate: ") + snd_strerror(err));
104          }          }
105    
106          if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, Channels)) < 0) {          if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, uiAlsaChannels)) < 0) {
107              throw AudioOutputException(String("Error setting number of channels: ") + snd_strerror(err));              throw AudioOutputException(String("Error setting number of channels: ") + snd_strerror(err));
108          }          }
109    
# Line 141  namespace LinuxSampler { Line 145  namespace LinuxSampler {
145          }          }
146    
147          // allocate Alsa output buffer          // allocate Alsa output buffer
148          pAlsaOutputBuffer = new int16_t[Channels * FragmentSize];          pAlsaOutputBuffer = new int16_t[uiAlsaChannels * FragmentSize];
149    
150          // 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
151          for (int i = 0; i < Channels; i++) this->Channels.push_back(new AudioChannel(FragmentSize));          for (int i = 0; i < uiAlsaChannels; i++) this->Channels.push_back(new AudioChannel(FragmentSize));
152      }      }
153    
154      AudioOutputDeviceAlsa::~AudioOutputDeviceAlsa() {      AudioOutputDeviceAlsa::~AudioOutputDeviceAlsa() {
# Line 164  namespace LinuxSampler { Line 168  namespace LinuxSampler {
168          }          }
169      }      }
170    
171        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::CreateParameters(std::map<String,String> Parameters) {
172            std::map<String,DeviceCreationParameter*> result;
173            result["CARD"]         = new ParameterCard(this, Parameters["CARD"]);                 // additional parameter, individually for this driver
174            result["FRAGMENTS"]    = new ParameterFragments(this, Parameters["FRAGMENTS"]);       // additional parameter, individually for this driver
175            result["FRAGMENTSIZE"] = new ParameterFragmentSize(this, Parameters["FRAGMENTSIZE"]); // additional parameter, individually for this driver
176            return result;
177        }
178    
179      /**      /**
180       *  Checks if sound card supports the chosen parameters.       *  Checks if sound card supports the chosen parameters.
181       *       *
182       *  @returns  true if hardware supports it       *  @returns  true if hardware supports it
183       */       */
184      bool AudioOutputDeviceAlsa::HardwareParametersSupported(uint channels, int samplerate, uint numfragments, uint fragmentsize) {      bool AudioOutputDeviceAlsa::HardwareParametersSupported(String card, uint channels, int samplerate, uint numfragments, uint fragmentsize) {
185          pcm_name = "hw:0,0";          pcm_name = "hw:" + card;
186          if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), stream, 0) < 0) return false;          if (snd_pcm_open(&pcm_handle, pcm_name.c_str(), stream, 0) < 0) return false;
187          snd_pcm_hw_params_alloca(&hwparams);          snd_pcm_hw_params_alloca(&hwparams);
188          if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {          if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
# Line 242  namespace LinuxSampler { Line 254  namespace LinuxSampler {
254          return uiSamplerate;          return uiSamplerate;
255      }      }
256    
257        String AudioOutputDeviceAlsa::Description() {
258            return "Advanced Linux Sound Architecture";
259        }
260    
261        String AudioOutputDeviceAlsa::Version() {
262           String s = "$Revision: 1.4 $";
263           return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
264        }
265    
266        std::map<String,DeviceCreationParameter*> AudioOutputDeviceAlsa::AvailableParameters() {
267            // FIXME: not a good solution to get the commot parameters (ACTIVE,SAMPERATE,CHANNELS which have to be offered by all audio output drivers)
268            std::map<String,DeviceCreationParameter*> available_parameters = AudioOutputDevice::AvailableParameters();
269            static ParameterCard         param_card(NULL);
270            static ParameterFragments    param_fragments(NULL);
271            static ParameterFragmentSize param_fragmentsize(NULL);
272            available_parameters["CARD"]         = &param_card;         // additional parameter, individually for this driver
273            available_parameters["FRAGMENTS"]    = &param_fragments;    // additional parameter, individually for this driver
274            available_parameters["FRAGMENTSIZE"] = &param_fragmentsize; // additional parameter, individually for this driver
275            return available_parameters;
276        }
277    
278        /**
279         * Entry point for the thread.
280         */
281      int AudioOutputDeviceAlsa::Main() {      int AudioOutputDeviceAlsa::Main() {
282          while (true) {          while (true) {
283    

Legend:
Removed from v.122  
changed lines
  Added in v.123

  ViewVC Help
Powered by ViewVC