3 * Copyright (C) 2010-2013 Team XBMC
6 * This Program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This Program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with XBMC; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
23 #include "threads/Thread.h"
25 #include "ActiveAESink.h"
26 #include "ActiveAEResample.h"
27 #include "Interfaces/AEStream.h"
28 #include "Interfaces/AESound.h"
29 #include "AEFactory.h"
30 #include "guilib/DispResource.h"
33 #include "DllAvFormat.h"
34 #include "DllAvCodec.h"
35 #include "DllAvUtil.h"
44 class CActiveAEStream;
50 std::string passthoughdevice;
55 bool truehdpassthrough;
56 bool dtshdpassthrough;
61 unsigned int samplerate;
62 AEQuality resampleQuality;
65 class CActiveAEControlProtocol : public Protocol
68 CActiveAEControlProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {};
99 class CActiveAEDataProtocol : public Protocol
102 CActiveAEDataProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {};
124 AEAudioFormat format;
125 unsigned int options;
128 struct MsgStreamSample
130 CSampleBuffer *buffer;
131 CActiveAEStream *stream;
134 struct MsgStreamParameter
136 CActiveAEStream *stream;
146 CActiveAEStream *stream;
155 void Reset(unsigned int sampleRate);
156 void UpdateSinkDelay(double delay, int samples);
157 void AddSamples(int samples, std::list<CActiveAEStream*> &streams);
159 float GetDelay(CActiveAEStream *stream);
160 float GetCacheTime(CActiveAEStream *stream);
161 float GetCacheTotal(CActiveAEStream *stream);
162 float GetWaterLevel();
163 void SetSuspended(bool state);
164 void SetSinkCacheTotal(float time) { m_sinkCacheTotal = time; }
166 CCriticalSection *GetLock() { return &m_lock; }
169 float m_sinkCacheTotal;
170 int m_bufferedSamples;
171 unsigned int m_sinkSampleRate;
172 unsigned int m_sinkUpdate;
174 CCriticalSection m_lock;
177 #if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
178 class CActiveAE : public IAE, public IDispResource, private CThread
180 class CActiveAE : public IAE, private CThread
184 friend class ::CAEFactory;
185 friend class CActiveAESound;
186 friend class CActiveAEStream;
187 friend class CSoundPacket;
188 friend class CActiveAEBufferPoolResample;
190 virtual ~CActiveAE();
191 virtual bool Initialize();
194 virtual void Shutdown();
195 virtual bool Suspend();
196 virtual bool Resume();
197 virtual bool IsSuspended();
198 virtual void OnSettingsChange(const std::string& setting);
200 virtual float GetVolume();
201 virtual void SetVolume(const float volume);
202 virtual void SetMute(const bool enabled);
203 virtual bool IsMuted();
204 virtual void SetSoundMode(const int mode);
206 /* returns a new stream for data in the specified format */
207 virtual IAEStream *MakeStream(enum AEDataFormat dataFormat, unsigned int sampleRate, unsigned int encodedSampleRate, CAEChannelInfo channelLayout, unsigned int options = 0);
208 virtual IAEStream *FreeStream(IAEStream *stream);
210 /* returns a new sound object */
211 virtual IAESound *MakeSound(const std::string& file);
212 virtual void FreeSound(IAESound *sound);
214 virtual void GarbageCollect() {};
216 virtual void EnumerateOutputDevices(AEDeviceList &devices, bool passthrough);
217 virtual std::string GetDefaultDevice(bool passthrough);
218 virtual bool SupportsRaw(AEDataFormat format);
219 virtual bool SupportsSilenceTimeout();
220 virtual bool SupportsQualityLevel(enum AEQuality level);
221 virtual bool IsSettingVisible(const std::string &settingId);
223 virtual void RegisterAudioCallback(IAudioCallback* pCallback);
224 virtual void UnregisterAudioCallback();
226 virtual void OnLostDevice();
227 virtual void OnResetDevice();
230 void PlaySound(CActiveAESound *sound);
231 uint8_t **AllocSoundSample(SampleConfig &config, int &samples, int &bytes_per_sample, int &planes, int &linesize);
232 void FreeSoundSample(uint8_t **data);
233 float GetDelay(CActiveAEStream *stream) { return m_stats.GetDelay(stream); }
234 float GetCacheTime(CActiveAEStream *stream) { return m_stats.GetCacheTime(stream); }
235 float GetCacheTotal(CActiveAEStream *stream) { return m_stats.GetCacheTotal(stream); }
236 void FlushStream(CActiveAEStream *stream);
237 void PauseStream(CActiveAEStream *stream, bool pause);
238 void StopSound(CActiveAESound *sound);
239 void SetStreamAmplification(CActiveAEStream *stream, float amplify);
240 void SetStreamReplaygain(CActiveAEStream *stream, float rgain);
241 void SetStreamVolume(CActiveAEStream *stream, float volume);
242 void SetStreamResampleRatio(CActiveAEStream *stream, double ratio);
243 void SetStreamFade(CActiveAEStream *stream, float from, float target, unsigned int millis);
247 void StateMachine(int signal, Protocol *port, Message *msg);
250 void UnconfigureSink();
251 bool IsSinkCompatible(const AEAudioFormat format, const std::string &device);
255 bool NeedReconfigureBuffers();
256 bool NeedReconfigureSink();
257 void ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &settings, int *mode = NULL);
258 void Configure(AEAudioFormat *desiredFmt = NULL);
259 AEAudioFormat GetInputFormat(AEAudioFormat *desiredFmt = NULL);
260 CActiveAEStream* CreateStream(MsgStreamNew *streamMsg);
261 void DiscardStream(CActiveAEStream *stream);
262 void SFlushStream(CActiveAEStream *stream);
264 void ClearDiscardedBuffers();
265 void SStopSound(CActiveAESound *sound);
266 void DiscardSound(CActiveAESound *sound);
267 void ChangeResamplers();
272 void ResampleSounds();
273 bool ResampleSound(CActiveAESound *sound);
274 void MixSounds(CSoundPacket &dstSample);
275 void Deamplify(CSoundPacket &dstSample);
277 bool CompareFormat(AEAudioFormat &lhs, AEAudioFormat &rhs);
280 CEvent m_outMsgEvent;
281 CActiveAEControlProtocol m_controlPort;
282 CActiveAEDataProtocol m_dataPort;
284 bool m_bStateMachineSelfTrigger;
288 XbmcThreads::EndTime m_extDrainTimer;
298 CActiveAESink m_sink;
299 AEAudioFormat m_sinkFormat;
300 AEAudioFormat m_sinkRequestFormat;
301 AEAudioFormat m_encoderFormat;
302 AEAudioFormat m_internalFormat;
303 AEAudioFormat m_inputFormat;
304 AudioSettings m_settings;
305 CEngineStats m_stats;
306 IAEEncoder *m_encoder;
309 CActiveAEBufferPoolResample *m_sinkBuffers;
310 CActiveAEBufferPoolResample *m_vizBuffers;
311 CActiveAEBufferPool *m_vizBuffersInput;
312 CActiveAEBufferPool *m_silenceBuffers; // needed to drive gui sounds if we have no streams
313 CActiveAEBufferPool *m_encoderBuffers;
316 std::list<CActiveAEStream*> m_streams;
317 std::list<CActiveAEBufferPool*> m_discardBufferPools;
322 CActiveAESound *sound;
325 std::list<SoundState> m_sounds_playing;
326 std::vector<CActiveAESound*> m_sounds;
331 bool m_sinkHasVolume;
334 IAudioCallback *m_audioCallback;
335 bool m_vizInitialized;
336 CCriticalSection m_vizLock;
339 DllAvFormat m_dllAvFormat;
340 DllAvCodec m_dllAvCodec;
341 DllAvUtil m_dllAvUtil;
343 // polled via the interface