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"
34 #include "DllAvFormat.h"
35 #include "DllAvCodec.h"
36 #include "DllAvUtil.h"
45 class CActiveAEStream;
51 std::string passthoughdevice;
57 bool truehdpassthrough;
58 bool dtshdpassthrough;
64 unsigned int samplerate;
65 AEQuality resampleQuality;
68 class CActiveAEControlProtocol : public Protocol
71 CActiveAEControlProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {};
104 class CActiveAEDataProtocol : public Protocol
107 CActiveAEDataProtocol(std::string name, CEvent* inEvent, CEvent *outEvent) : Protocol(name, inEvent, outEvent) {};
129 AEAudioFormat format;
130 unsigned int options;
133 struct MsgStreamSample
135 CSampleBuffer *buffer;
136 CActiveAEStream *stream;
139 struct MsgStreamParameter
141 CActiveAEStream *stream;
151 CActiveAEStream *stream;
160 void Reset(unsigned int sampleRate);
161 void UpdateSinkDelay(double delay, int samples);
162 void AddSamples(int samples, std::list<CActiveAEStream*> &streams);
164 float GetDelay(CActiveAEStream *stream);
165 float GetCacheTime(CActiveAEStream *stream);
166 float GetCacheTotal(CActiveAEStream *stream);
167 float GetWaterLevel();
168 void SetSuspended(bool state);
169 void SetSinkCacheTotal(float time) { m_sinkCacheTotal = time; }
170 void SetSinkLatency(float time) { m_sinkLatency = time; }
172 CCriticalSection *GetLock() { return &m_lock; }
175 float m_sinkCacheTotal;
177 int m_bufferedSamples;
178 unsigned int m_sinkSampleRate;
179 unsigned int m_sinkUpdate;
181 CCriticalSection m_lock;
184 #if defined(HAS_GLX) || defined(TARGET_DARWIN)
185 class CActiveAE : public IAE, public IDispResource, private CThread
187 class CActiveAE : public IAE, private CThread
191 friend class ::CAEFactory;
192 friend class CActiveAESound;
193 friend class CActiveAEStream;
194 friend class CSoundPacket;
195 friend class CActiveAEBufferPoolResample;
197 virtual ~CActiveAE();
198 virtual bool Initialize();
201 virtual void Shutdown();
202 virtual bool Suspend();
203 virtual bool Resume();
204 virtual bool IsSuspended();
205 virtual void OnSettingsChange(const std::string& setting);
207 virtual float GetVolume();
208 virtual void SetVolume(const float volume);
209 virtual void SetMute(const bool enabled);
210 virtual bool IsMuted();
211 virtual void SetSoundMode(const int mode);
213 /* returns a new stream for data in the specified format */
214 virtual IAEStream *MakeStream(enum AEDataFormat dataFormat, unsigned int sampleRate, unsigned int encodedSampleRate, CAEChannelInfo channelLayout, unsigned int options = 0);
215 virtual IAEStream *FreeStream(IAEStream *stream);
217 /* returns a new sound object */
218 virtual IAESound *MakeSound(const std::string& file);
219 virtual void FreeSound(IAESound *sound);
221 virtual void GarbageCollect() {};
223 virtual void EnumerateOutputDevices(AEDeviceList &devices, bool passthrough);
224 virtual std::string GetDefaultDevice(bool passthrough);
225 virtual bool SupportsRaw(AEDataFormat format, int samplerate);
226 virtual bool SupportsSilenceTimeout();
227 virtual bool SupportsQualityLevel(enum AEQuality level);
228 virtual bool IsSettingVisible(const std::string &settingId);
229 virtual void KeepConfiguration(unsigned int millis);
230 virtual void DeviceChange();
232 virtual void RegisterAudioCallback(IAudioCallback* pCallback);
233 virtual void UnregisterAudioCallback();
235 virtual void OnLostDevice();
236 virtual void OnResetDevice();
237 virtual void OnAppFocusChange(bool focus);
240 void PlaySound(CActiveAESound *sound);
241 uint8_t **AllocSoundSample(SampleConfig &config, int &samples, int &bytes_per_sample, int &planes, int &linesize);
242 void FreeSoundSample(uint8_t **data);
243 float GetDelay(CActiveAEStream *stream) { return m_stats.GetDelay(stream); }
244 float GetCacheTime(CActiveAEStream *stream) { return m_stats.GetCacheTime(stream); }
245 float GetCacheTotal(CActiveAEStream *stream) { return m_stats.GetCacheTotal(stream); }
246 void FlushStream(CActiveAEStream *stream);
247 void PauseStream(CActiveAEStream *stream, bool pause);
248 void StopSound(CActiveAESound *sound);
249 void SetStreamAmplification(CActiveAEStream *stream, float amplify);
250 void SetStreamReplaygain(CActiveAEStream *stream, float rgain);
251 void SetStreamVolume(CActiveAEStream *stream, float volume);
252 void SetStreamResampleRatio(CActiveAEStream *stream, double ratio);
253 void SetStreamFade(CActiveAEStream *stream, float from, float target, unsigned int millis);
257 void StateMachine(int signal, Protocol *port, Message *msg);
260 void UnconfigureSink();
264 bool NeedReconfigureBuffers();
265 bool NeedReconfigureSink();
266 void ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &settings, int *mode = NULL);
267 void Configure(AEAudioFormat *desiredFmt = NULL);
268 AEAudioFormat GetInputFormat(AEAudioFormat *desiredFmt = NULL);
269 CActiveAEStream* CreateStream(MsgStreamNew *streamMsg);
270 void DiscardStream(CActiveAEStream *stream);
271 void SFlushStream(CActiveAEStream *stream);
273 void ClearDiscardedBuffers();
274 void SStopSound(CActiveAESound *sound);
275 void DiscardSound(CActiveAESound *sound);
276 void ChangeResamplers();
281 void ResampleSounds();
282 bool ResampleSound(CActiveAESound *sound);
283 void MixSounds(CSoundPacket &dstSample);
284 void Deamplify(CSoundPacket &dstSample);
286 bool CompareFormat(AEAudioFormat &lhs, AEAudioFormat &rhs);
289 CEvent m_outMsgEvent;
290 CActiveAEControlProtocol m_controlPort;
291 CActiveAEDataProtocol m_dataPort;
293 bool m_bStateMachineSelfTrigger;
297 XbmcThreads::EndTime m_extDrainTimer;
298 unsigned int m_extKeepConfig;
300 std::queue<time_t> m_extLastDeviceChange;
309 CActiveAESink m_sink;
310 AEAudioFormat m_sinkFormat;
311 AEAudioFormat m_sinkRequestFormat;
312 AEAudioFormat m_encoderFormat;
313 AEAudioFormat m_internalFormat;
314 AEAudioFormat m_inputFormat;
315 AudioSettings m_settings;
316 CEngineStats m_stats;
317 IAEEncoder *m_encoder;
318 std::string m_currDevice;
321 CActiveAEBufferPoolResample *m_sinkBuffers;
322 CActiveAEBufferPoolResample *m_vizBuffers;
323 CActiveAEBufferPool *m_vizBuffersInput;
324 CActiveAEBufferPool *m_silenceBuffers; // needed to drive gui sounds if we have no streams
325 CActiveAEBufferPool *m_encoderBuffers;
328 std::list<CActiveAEStream*> m_streams;
329 std::list<CActiveAEBufferPool*> m_discardBufferPools;
334 CActiveAESound *sound;
337 std::list<SoundState> m_sounds_playing;
338 std::vector<CActiveAESound*> m_sounds;
340 float m_volume; // volume on a 0..1 scale corresponding to a proportion along the dB scale
341 float m_volumeScaled; // multiplier to scale samples in order to achieve the volume specified in m_volume
343 bool m_sinkHasVolume;
346 IAudioCallback *m_audioCallback;
347 bool m_vizInitialized;
348 CCriticalSection m_vizLock;
351 DllAvFormat m_dllAvFormat;
352 DllAvCodec m_dllAvCodec;
353 DllAvUtil m_dllAvUtil;
355 // polled via the interface