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 "cores/AudioEngine/Interfaces/AEStream.h"
28 #include "cores/AudioEngine/Interfaces/AESound.h"
29 #include "cores/AudioEngine/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;
56 bool truehdpassthrough;
57 bool dtshdpassthrough;
63 unsigned int samplerate;
64 AEQuality resampleQuality;
67 class CActiveAEControlProtocol : public Protocol
70 CActiveAEControlProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {};
101 class CActiveAEDataProtocol : public Protocol
104 CActiveAEDataProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {};
126 AEAudioFormat format;
127 unsigned int options;
130 struct MsgStreamSample
132 CSampleBuffer *buffer;
133 CActiveAEStream *stream;
136 struct MsgStreamParameter
138 CActiveAEStream *stream;
148 CActiveAEStream *stream;
157 void Reset(unsigned int sampleRate);
158 void UpdateSinkDelay(double delay, int samples);
159 void AddSamples(int samples, std::list<CActiveAEStream*> &streams);
161 float GetDelay(CActiveAEStream *stream);
162 float GetCacheTime(CActiveAEStream *stream);
163 float GetCacheTotal(CActiveAEStream *stream);
164 float GetWaterLevel();
165 void SetSuspended(bool state);
166 void SetSinkCacheTotal(float time) { m_sinkCacheTotal = time; }
167 void SetSinkLatency(float time) { m_sinkLatency = time; }
169 CCriticalSection *GetLock() { return &m_lock; }
172 float m_sinkCacheTotal;
174 int m_bufferedSamples;
175 unsigned int m_sinkSampleRate;
176 unsigned int m_sinkUpdate;
178 CCriticalSection m_lock;
181 #if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
182 class CActiveAE : public IAE, public IDispResource, private CThread
184 class CActiveAE : public IAE, private CThread
188 friend class ::CAEFactory;
189 friend class CActiveAESound;
190 friend class CActiveAEStream;
191 friend class CSoundPacket;
192 friend class CActiveAEBufferPoolResample;
194 virtual ~CActiveAE();
195 virtual bool Initialize();
198 virtual void Shutdown();
199 virtual bool Suspend();
200 virtual bool Resume();
201 virtual bool IsSuspended();
202 virtual void OnSettingsChange(const std::string& setting);
204 virtual float GetVolume();
205 virtual void SetVolume(const float volume);
206 virtual void SetMute(const bool enabled);
207 virtual bool IsMuted();
208 virtual void SetSoundMode(const int mode);
210 /* returns a new stream for data in the specified format */
211 virtual IAEStream *MakeStream(enum AEDataFormat dataFormat, unsigned int sampleRate, unsigned int encodedSampleRate, CAEChannelInfo channelLayout, unsigned int options = 0);
212 virtual IAEStream *FreeStream(IAEStream *stream);
214 /* returns a new sound object */
215 virtual IAESound *MakeSound(const std::string& file);
216 virtual void FreeSound(IAESound *sound);
218 virtual void GarbageCollect() {};
220 virtual void EnumerateOutputDevices(AEDeviceList &devices, bool passthrough);
221 virtual std::string GetDefaultDevice(bool passthrough);
222 virtual bool SupportsRaw(AEDataFormat format);
223 virtual bool SupportsSilenceTimeout();
224 virtual bool SupportsQualityLevel(enum AEQuality level);
225 virtual bool IsSettingVisible(const std::string &settingId);
226 virtual void KeepConfiguration(unsigned int millis);
228 virtual void RegisterAudioCallback(IAudioCallback* pCallback);
229 virtual void UnregisterAudioCallback();
231 virtual void OnLostDevice();
232 virtual void OnResetDevice();
235 void PlaySound(CActiveAESound *sound);
236 uint8_t **AllocSoundSample(SampleConfig &config, int &samples, int &bytes_per_sample, int &planes, int &linesize);
237 void FreeSoundSample(uint8_t **data);
238 float GetDelay(CActiveAEStream *stream) { return m_stats.GetDelay(stream); }
239 float GetCacheTime(CActiveAEStream *stream) { return m_stats.GetCacheTime(stream); }
240 float GetCacheTotal(CActiveAEStream *stream) { return m_stats.GetCacheTotal(stream); }
241 void FlushStream(CActiveAEStream *stream);
242 void PauseStream(CActiveAEStream *stream, bool pause);
243 void StopSound(CActiveAESound *sound);
244 void SetStreamAmplification(CActiveAEStream *stream, float amplify);
245 void SetStreamReplaygain(CActiveAEStream *stream, float rgain);
246 void SetStreamVolume(CActiveAEStream *stream, float volume);
247 void SetStreamResampleRatio(CActiveAEStream *stream, double ratio);
248 void SetStreamFade(CActiveAEStream *stream, float from, float target, unsigned int millis);
252 void StateMachine(int signal, Protocol *port, Message *msg);
255 void UnconfigureSink();
259 bool NeedReconfigureBuffers();
260 bool NeedReconfigureSink();
261 void ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &settings, int *mode = NULL);
262 void Configure(AEAudioFormat *desiredFmt = NULL);
263 AEAudioFormat GetInputFormat(AEAudioFormat *desiredFmt = NULL);
264 CActiveAEStream* CreateStream(MsgStreamNew *streamMsg);
265 void DiscardStream(CActiveAEStream *stream);
266 void SFlushStream(CActiveAEStream *stream);
268 void ClearDiscardedBuffers();
269 void SStopSound(CActiveAESound *sound);
270 void DiscardSound(CActiveAESound *sound);
271 void ChangeResamplers();
276 void ResampleSounds();
277 bool ResampleSound(CActiveAESound *sound);
278 void MixSounds(CSoundPacket &dstSample);
279 void Deamplify(CSoundPacket &dstSample);
281 bool CompareFormat(AEAudioFormat &lhs, AEAudioFormat &rhs);
284 CEvent m_outMsgEvent;
285 CActiveAEControlProtocol m_controlPort;
286 CActiveAEDataProtocol m_dataPort;
288 bool m_bStateMachineSelfTrigger;
292 XbmcThreads::EndTime m_extDrainTimer;
293 unsigned int m_extKeepConfig;
303 CActiveAESink m_sink;
304 AEAudioFormat m_sinkFormat;
305 AEAudioFormat m_sinkRequestFormat;
306 AEAudioFormat m_encoderFormat;
307 AEAudioFormat m_internalFormat;
308 AEAudioFormat m_inputFormat;
309 AudioSettings m_settings;
310 CEngineStats m_stats;
311 IAEEncoder *m_encoder;
312 std::string m_currDevice;
315 CActiveAEBufferPoolResample *m_sinkBuffers;
316 CActiveAEBufferPoolResample *m_vizBuffers;
317 CActiveAEBufferPool *m_vizBuffersInput;
318 CActiveAEBufferPool *m_silenceBuffers; // needed to drive gui sounds if we have no streams
319 CActiveAEBufferPool *m_encoderBuffers;
322 std::list<CActiveAEStream*> m_streams;
323 std::list<CActiveAEBufferPool*> m_discardBufferPools;
328 CActiveAESound *sound;
331 std::list<SoundState> m_sounds_playing;
332 std::vector<CActiveAESound*> m_sounds;
336 bool m_sinkHasVolume;
339 IAudioCallback *m_audioCallback;
340 bool m_vizInitialized;
341 CCriticalSection m_vizLock;
344 DllAvFormat m_dllAvFormat;
345 DllAvCodec m_dllAvCodec;
346 DllAvUtil m_dllAvUtil;
348 // polled via the interface