1 /***************************************************************************
2  *                                                                         *
3  *   LinuxSampler - modular, streaming capable sampler                     *
4  *                                                                         *
5  *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6  *   Copyright (C) 2005 - 2020 Christian Schoenebeck                       *
7  *                                                                         *
8  *   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  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the Free Software           *
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
21  *   MA  02111-1307  USA                                                   *
22  ***************************************************************************/
23 
24 #ifndef __LS_AUDIOOUTPUTDEVICEALSA_H__
25 #define __LS_AUDIOOUTPUTDEVICEALSA_H__
26 
27 #include <string.h>
28 #include <alsa/asoundlib.h>
29 
30 #include "../../common/global_private.h"
31 #include "../../common/Thread.h"
32 #include "AudioOutputDevice.h"
33 #include "AudioChannel.h"
34 #include "../DeviceParameter.h"
35 
36 namespace LinuxSampler {
37 
38     /** ALSA audio output driver
39      *
40      * Implements audio output to the Advanced Linux Sound Architecture (ALSA).
41      */
42     class AudioOutputDeviceAlsa : public AudioOutputDevice, protected Thread {
43         public:
44             AudioOutputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters);
45             ~AudioOutputDeviceAlsa();
46 
47             // derived abstract methods from class 'AudioOutputDevice'
48             virtual void Play() OVERRIDE;
49             virtual bool IsPlaying() OVERRIDE;
50             virtual void Stop() OVERRIDE;
51             virtual uint MaxSamplesPerCycle() OVERRIDE;
52             virtual uint SampleRate() OVERRIDE;
53             virtual AudioChannel* CreateChannel(uint ChannelNr) OVERRIDE;
54             virtual String Driver() OVERRIDE;
55 
56             static String Name();
57             static String Description();
58             static String Version();
59 
60             /** Device Parameter 'CARD'
61              *
62              * Used to select the desired ALSA sound card.
63              */
64             class ParameterCard : public DeviceCreationParameterString {
65                 public:
66                     ParameterCard();
67                     ParameterCard(String s) throw (Exception);
68                     virtual String Description() OVERRIDE;
69                     virtual bool   Fix() OVERRIDE;
70                     virtual bool   Mandatory() OVERRIDE;
71                     virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() OVERRIDE;
72                     virtual optional<String>    DefaultAsString(std::map<String,String> Parameters) OVERRIDE;
73                     virtual std::vector<String> PossibilitiesAsString(std::map<String,String> Parameters) OVERRIDE;
74                     virtual void                OnSetValue(String s) throw (Exception) OVERRIDE;
75                     static String Name();
76             };
77 
78             /** Device Parameter 'SAMPLERATE'
79              *
80              * Used to set the sample rate of the audio output device.
81              */
82             class ParameterSampleRate : public AudioOutputDevice::ParameterSampleRate {
83                 public:
84                     ParameterSampleRate();
85                     ParameterSampleRate(String s);
86                     virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() OVERRIDE;
87                     virtual optional<int> DefaultAsInt(std::map<String,String> Parameters) OVERRIDE;
88                     virtual optional<int> RangeMinAsInt(std::map<String,String> Parameters) OVERRIDE;
89                     virtual optional<int> RangeMaxAsInt(std::map<String,String> Parameters) OVERRIDE;
90             };
91 
92             /** Device Parameters 'CHANNELS'
93              *
94              * Used to increase / decrease the number of audio channels of
95              * audio output device.
96              */
97             class ParameterChannels : public AudioOutputDevice::ParameterChannels {
98                 public:
99                     ParameterChannels();
100                     ParameterChannels(String s);
101                     virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() OVERRIDE;
102                     virtual optional<int> DefaultAsInt(std::map<String,String> Parameters) OVERRIDE;
103                     virtual optional<int> RangeMinAsInt(std::map<String,String> Parameters) OVERRIDE;
104                     virtual optional<int> RangeMaxAsInt(std::map<String,String> Parameters) OVERRIDE;
105             };
106 
107             /** Device Parameter 'FRAGMENTS'
108              *
109              * Used to select the number of audio fragments / periods.
110              */
111             class ParameterFragments : public DeviceCreationParameterInt {
112                 public:
113                     ParameterFragments();
114                     ParameterFragments(String s) throw (Exception);
115                     virtual String Description() OVERRIDE;
116                     virtual bool   Fix() OVERRIDE;
117                     virtual bool   Mandatory() OVERRIDE;
118                     virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() OVERRIDE;
119                     virtual optional<int>    DefaultAsInt(std::map<String,String> Parameters) OVERRIDE;
120                     virtual optional<int>    RangeMinAsInt(std::map<String,String> Parameters) OVERRIDE;
121                     virtual optional<int>    RangeMaxAsInt(std::map<String,String> Parameters) OVERRIDE;
122                     virtual std::vector<int> PossibilitiesAsInt(std::map<String,String> Parameters) OVERRIDE;
123                     virtual void             OnSetValue(int i) throw (Exception) OVERRIDE;
124                     static String Name();
125             };
126 
127             /** Device Parameter 'FRAGMENTSIZE'
128              *
129              * Used to set the audio fragment size / period size.
130              */
131             class ParameterFragmentSize : public DeviceCreationParameterInt {
132                 public:
133                     ParameterFragmentSize();
134                     ParameterFragmentSize(String s) throw (Exception);
135                     virtual String Description() OVERRIDE;
136                     virtual bool   Fix() OVERRIDE;
137                     virtual bool   Mandatory() OVERRIDE;
138                     virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() OVERRIDE;
139                     virtual optional<int>    DefaultAsInt(std::map<String,String> Parameters) OVERRIDE;
140                     virtual optional<int>    RangeMinAsInt(std::map<String,String> Parameters) OVERRIDE;
141                     virtual optional<int>    RangeMaxAsInt(std::map<String,String> Parameters) OVERRIDE;
142                     virtual std::vector<int> PossibilitiesAsInt(std::map<String,String> Parameters) OVERRIDE;
143                     virtual void             OnSetValue(int i) throw (Exception) OVERRIDE;
144                     static String Name();
145             };
146 
147         protected:
148             int Main() OVERRIDE;  ///< Implementation of virtual method from class Thread
149 
150         private:
151             uint                 uiAlsaChannels;
152             uint                 uiSamplerate;
153             uint                 FragmentSize;
154             int16_t*             pAlsaOutputBuffer; ///< This is the buffer where the final mix will be copied to and send to the sound card
155             String               pcm_name;          ///< Name of the PCM device, like plughw:0,0 the first number is the number of the soundcard, the second number is the number of the device.
156             snd_pcm_t*           pcm_handle;        ///< Handle for the PCM device
157             snd_pcm_stream_t     stream;
158             snd_pcm_hw_params_t* hwparams;          ///< This structure contains information about the hardware and can be used to specify the configuration to be used for the PCM stream.
159             snd_pcm_sw_params_t* swparams;
160 
161             int  Output();
162             bool HardwareParametersSupported(String card, uint channels, int samplerate, uint numfragments, uint fragmentsize) throw (AudioOutputException);
163     };
164 }
165 
166 #endif // __LS_AUDIOOUTPUTDEVICEALSA_H__
167