/[svn]/linuxsampler/trunk/src/audiodriver/AudioOutputDevice.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/audiodriver/AudioOutputDevice.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 143 - (show annotations) (download) (as text)
Wed Jun 23 18:54:08 2004 UTC (19 years, 10 months ago) by capela
File MIME type: text/x-c++hdr
File size: 15325 byte(s)
* SET CHANNEL AUDIO_OUTPUT_TYPE <chan> <driver> command is back!
  creates an audio output device instance of the given driver type
  ('Jack' or 'Alsa') with default parameters if none exists,
  otherwise it just picks the first available device and assign
  it to the intended sampler channel.

* The AudioOutputDevice class get's a new pure virtual method,
  Driver(), which is implemented on both of the existing inherited
  classes, AudioOutputDeviceAlsa and AudioOutputDeviceJack, with
  the sole purpose to return the driver type name as a String
  ('Alsa' and 'Jack', respectively).

* The quoting on the filename argument for the LOAD INSTRUMENT
  command has been made optional; you can have both ways, with
  single quotes or none, keeping compability with older LSCP
  specification.

* An additional sanity check is made on LOAD INSTRUMENT, whether
  the sampler channel has an audio output device assigned, thus
  preventing the server from crashing on instrument file load.

* The GET AUDIO_OUTPUT_DEVICE INFO now includes the missing
  'driver' item, as predicted by the draft protocol document.

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #ifndef __LS_AUDIOOUTPUTDEVICE_H__
24 #define __LS_AUDIOOUTPUTDEVICE_H__
25
26 #include <set>
27 #include <map>
28 #include <vector>
29 #include <stdexcept>
30
31 #include "../common/global.h"
32 #include "../common/LinuxSamplerException.h"
33 #include "../drivers/DeviceParameter.h"
34 #include "../engines/common/Engine.h"
35 #include "AudioChannel.h"
36
37 namespace LinuxSampler {
38
39 // just symbol prototyping
40 class Engine;
41
42 /** Abstract base class for audio output drivers in LinuxSampler
43 *
44 * This class will be derived by specialized classes which implement the
45 * connection to a specific audio output system (e.g. Alsa, Jack,
46 * CoreAudio).
47 */
48 class AudioOutputDevice {
49 public:
50
51
52 /////////////////////////////////////////////////////////////////
53 // type definitions
54
55 class ParameterActive : public DeviceCreationParameterBool {
56 public:
57 ParameterActive(AudioOutputDevice* pDevice) { this->pDevice = pDevice; InitWithDefault(); }
58 ParameterActive(AudioOutputDevice* pDevice, String active) throw (LinuxSamplerException) : DeviceCreationParameterBool(active) { this->pDevice = pDevice; }
59 virtual String Description() { return "Enable / disable device"; }
60 virtual bool Fix() { return false; }
61 virtual bool Mandatory() { return false; }
62 virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() { return std::map<String,DeviceCreationParameter*>(); }
63 virtual optional<bool> DefaultAsBool(std::map<String,String> Parameters) { return true; }
64 virtual void OnSetValue(bool b) throw (LinuxSamplerException) { if (b) pDevice->Play(); else pDevice->Stop(); }
65 protected:
66 AudioOutputDevice* pDevice;
67 };
68
69 class ParameterSampleRate : public DeviceCreationParameterInt {
70 public:
71 ParameterSampleRate(AudioOutputDevice* pDevice) { this->pDevice = pDevice; InitWithDefault(); }
72 ParameterSampleRate(AudioOutputDevice* pDevice, String samplerate) throw (LinuxSamplerException) : DeviceCreationParameterInt(samplerate) { this->pDevice = pDevice; }
73 virtual String Description() { return "Output sample rate"; }
74 virtual bool Fix() { return true; }
75 virtual bool Mandatory() { return false; }
76 virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() { return std::map<String,DeviceCreationParameter*>(); }
77 virtual optional<int> DefaultAsInt(std::map<String,String> Parameters) { return 44100; }
78 virtual optional<int> RangeMinAsInt(std::map<String,String> Parameters) { return optional<int>::nothing; }
79 virtual optional<int> RangeMaxAsInt(std::map<String,String> Parameters) { return optional<int>::nothing; }
80 virtual std::vector<int> PossibilitiesAsInt(std::map<String,String> Parameters) { return std::vector<int>(); }
81 virtual void OnSetValue(int i) throw (LinuxSamplerException) { /* cannot happen, as parameter is fix */ }
82 protected:
83 AudioOutputDevice* pDevice;
84 };
85
86 class ParameterChannels : public DeviceCreationParameterInt {
87 public:
88 ParameterChannels(AudioOutputDevice* pDevice) { this->pDevice = pDevice; InitWithDefault(); }
89 ParameterChannels(AudioOutputDevice* pDevice, String channels) throw (LinuxSamplerException) : DeviceCreationParameterInt(channels) { this->pDevice = pDevice; }
90 virtual String Description() { return "Number of output channels"; }
91 virtual bool Fix() { return false; }
92 virtual bool Mandatory() { return false; }
93 virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() { return std::map<String,DeviceCreationParameter*>(); }
94 virtual optional<int> DefaultAsInt(std::map<String,String> Parameters) { return 2; }
95 virtual optional<int> RangeMinAsInt(std::map<String,String> Parameters) { return optional<int>::nothing; }
96 virtual optional<int> RangeMaxAsInt(std::map<String,String> Parameters) { return optional<int>::nothing; }
97 virtual std::vector<int> PossibilitiesAsInt(std::map<String,String> Parameters) { return std::vector<int>(); }
98 virtual void OnSetValue(int i) throw (LinuxSamplerException) { pDevice->AcquireChannels(i); }
99 protected:
100 AudioOutputDevice* pDevice;
101 };
102
103 template <class Parameter_T>
104 class OptionalParameter {
105 public:
106 static Parameter_T* New(AudioOutputDevice* pDevice, String val) { if (val == "") return (new Parameter_T(pDevice)); return (new Parameter_T(pDevice, val)); }
107 };
108
109 /////////////////////////////////////////////////////////////////
110 // abstract methods
111 // (these have to be implemented by the descendant)
112
113 /**
114 * Start playback of audio signal on the audio device. It's the
115 * responsibility of the implementing audio device to call the
116 * RenderAudio(uint Samples) method of all connected engines.
117 * This will cause the engines to continue to render 'Samples'
118 * number of audio sample points and the engines will
119 * automatically add their audio signals to the audio buffers of
120 * the audio channels of this audio device. So the implementing
121 * audio device just has to access the buffers of it's audio
122 * channels.
123 *
124 * @throws AudioOutputException if playback can not be started
125 * @see AudioChannel
126 */
127 virtual void Play() = 0;
128
129 /**
130 * Returns true if the audio device is currently playing back.
131 */
132 virtual bool IsPlaying() = 0;
133
134 /**
135 * Stop playback of audio signal on the audio device. The
136 * implementing audio device will stop calling the RenderAudio()
137 * method of all connected engines and close it's connection to
138 * audio output system.
139 */
140 virtual void Stop() = 0;
141
142 /**
143 * This method will usually be called by the sampler engines that
144 * are connected to this audio device to inform the audio device
145 * how much audio channels the engine(s) need. It's the
146 * responsibility of the audio device to offer that amount of
147 * audio channels - again: this is not an option this is a must!
148 * The engines will assume to be able to access those audio
149 * channels right after. If the audio driver is not able to offer
150 * that much channels, it can simply create mix channels which
151 * are then just mixed to the 'real' audio channels. See
152 * AudioChannel.h for details about channels and mix channels.
153 *
154 * @param Channels - amount of output channels required by
155 * a sampler engine
156 * @throws AudioOutputException if desired amount of channels
157 * cannot be offered
158 * @see AudioChannel
159 */
160 virtual void AcquireChannels(uint Channels) = 0;
161
162 /**
163 * Maximum amount of sample points the implementing audio
164 * device will ever demand the sampler engines to write in one
165 * fragment cycle / period. Simple audio device drivers usually
166 * have a fixed fragment size, so those devices just would return
167 * the fragment size in this method.
168 *
169 * @returns max. amount of sample points ever
170 */
171 virtual uint MaxSamplesPerCycle() = 0;
172
173 /**
174 * Playback samplerate the audio device uses. The sampler engines
175 * currently assume this to be a constant value for the whole
176 * life time of an instance of the implementing audio device.
177 *
178 * @returns sample rate in Hz
179 */
180 virtual uint SampleRate() = 0;
181
182 static std::map<String,DeviceCreationParameter*> AvailableParameters();
183
184 /**
185 * Return the audio output device driver type name.
186 */
187 virtual String Driver() = 0;
188
189
190
191 /////////////////////////////////////////////////////////////////
192 // normal methods
193 // (usually not to be overriden by descendant)
194
195 /**
196 * Connect given sampler engine to this audio output device. The
197 * engine will be added to the Engines container of this audio
198 * device and the engine will also automatically be informed
199 * about the connection.
200 *
201 * @param pEngine - sampler engine
202 */
203 void Connect(Engine* pEngine);
204
205 /**
206 * Disconnect given sampler engine from this audio output device.
207 * Removes given sampler engine reference from the Engines
208 * container of this audio device.
209 *
210 * @param pEngine - sampler engine
211 */
212 void Disconnect(Engine* pEngine);
213
214 /**
215 * Returns audio channel with index \a ChannelIndex or NULL if
216 * index out of bounds.
217 */
218 AudioChannel* Channel(uint ChannelIndex);
219
220 std::map<String,DeviceCreationParameter*> DeviceParameters();
221
222
223 protected:
224 std::set<Engine*> Engines; ///< All sampler engines that are connected to the audio output device.
225 std::vector<AudioChannel*> Channels; ///< All audio channels of the audio output device. This is just a container; the descendant has to create channels by himself.
226 std::map<String,DeviceCreationParameter*> Parameters; ///< All device parameters.
227
228 AudioOutputDevice(std::map<String,DeviceCreationParameter*> DriverParameters);
229
230 virtual ~AudioOutputDevice();
231
232 /**
233 * This method should be called by the AudioOutputDevice
234 * descendant to let all connected engines proceed to render the
235 * given amount of sample points. The engines will place their
236 * calculated audio data by themselfes into the buffers of the
237 * respective AudioChannel objects, so the implementing audio
238 * output device just has to copy the AudioChannel buffers to
239 * the output buffer(s) of its audio system.
240 *
241 * @returns 0 on success or the last error return code of one
242 * engine
243 */
244 int RenderAudio(uint Samples);
245
246 /**
247 * This can be called as an alternative to RenderAudio() for
248 * just writing silence to the audio output buffers and not
249 * calling the connected sampler engines for rendering audio, so
250 * to provide a method to stop playback if the used audio output
251 * system doesn't provide a better way.
252 *
253 * @returns 0 on success
254 */
255 int RenderSilence(uint Samples);
256
257 friend class Sampler; // allow Sampler class to destroy audio devices
258
259 private:
260 static std::map<String,DeviceCreationParameter*> CreateAvailableParameters();
261 };
262
263 /**
264 * Audio output exception that should be thrown by the AudioOutputDevice
265 * descendants in case initialization of the audio output system failed
266 * (which should be done in the constructor of the AudioOutputDevice
267 * descendant).
268 */
269 class AudioOutputException : public LinuxSamplerException {
270 public:
271 AudioOutputException(const std::string& msg) : LinuxSamplerException(msg) {}
272 };
273 }
274
275 #endif // __LS_AUDIOOUTPUTDEVICE_H__

  ViewVC Help
Powered by ViewVC