2 * Copyright (C) 2010-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
23 #include "ActiveAESink.h"
24 #include "cores/AudioEngine/Utils/AEUtil.h"
25 #include "utils/EndianSwap.h"
28 #include "settings/Settings.h"
30 using namespace ActiveAE;
32 CActiveAESink::CActiveAESink(CEvent *inMsgEvent) :
34 m_controlPort("SinkControlPort", inMsgEvent, &m_outMsgEvent),
35 m_dataPort("SinkDataPort", inMsgEvent, &m_outMsgEvent)
37 m_inMsgEvent = inMsgEvent;
40 m_convertBuffer = NULL;
44 void CActiveAESink::Start()
49 SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);
53 void CActiveAESink::Dispose()
58 m_controlPort.Purge();
64 m_sink->Deinitialize();
69 delete m_sampleOfSilence.pkt;
70 m_sampleOfSilence.pkt = NULL;
74 _aligned_free(m_convertBuffer);
75 m_convertBuffer = NULL;
79 AEDeviceType CActiveAESink::GetDeviceType(const std::string &device)
81 std::string dev = device;
83 CAESinkFactory::ParseDevice(dev, dri);
84 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
86 for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2)
88 CAEDeviceInfo& info = *itt2;
89 if (info.m_deviceName == dev)
90 return info.m_deviceType;
93 return AE_DEVTYPE_PCM;
96 bool CActiveAESink::HasPassthroughDevice()
98 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
100 for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2)
102 CAEDeviceInfo& info = *itt2;
103 if (info.m_deviceType != AE_DEVTYPE_PCM)
110 bool CActiveAESink::SupportsFormat(const std::string &device, AEDataFormat format, int samplerate)
112 std::string dev = device;
114 CAESinkFactory::ParseDevice(dev, dri);
115 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
117 if (dri == itt->m_sinkName)
119 for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2)
121 CAEDeviceInfo& info = *itt2;
122 if (info.m_deviceName == dev)
124 AEDataFormatList::iterator itt3;
125 itt3 = find(info.m_dataFormats.begin(), info.m_dataFormats.end(), format);
126 if (itt3 != info.m_dataFormats.end())
128 AESampleRateList::iterator itt4;
129 itt4 = find(info.m_sampleRates.begin(), info.m_sampleRates.end(), samplerate);
130 if (itt4 != info.m_sampleRates.end())
147 S_TOP_UNCONFIGURED, // 1
148 S_TOP_CONFIGURED, // 2
149 S_TOP_CONFIGURED_SUSPEND, // 3
150 S_TOP_CONFIGURED_IDLE, // 4
151 S_TOP_CONFIGURED_PLAY, // 5
152 S_TOP_CONFIGURED_SILENCE, // 6
155 int SINK_parentStates[] = {
157 0, //TOP_UNCONFIGURED
159 2, //TOP_CONFIGURED_SUSPEND
160 2, //TOP_CONFIGURED_IDLE
161 2, //TOP_CONFIGURED_PLAY
162 2, //TOP_CONFIGURED_SILENCE
165 void CActiveAESink::StateMachine(int signal, Protocol *port, Message *msg)
167 for (int state = m_state; ; state = SINK_parentStates[state])
172 if (port == &m_controlPort)
176 case CSinkControlProtocol::CONFIGURE:
178 data = (SinkConfig*)msg->data;
181 m_requestedFormat = data->format;
182 m_stats = data->stats;
183 m_device = *(data->device);
186 m_extSilenceTimer = 0;
187 m_extStreaming = false;
194 reply.format = m_sinkFormat;
195 reply.cacheTotal = m_sink->GetCacheTotal();
196 reply.latency = m_sink->GetLatency();
197 reply.hasVolume = m_sink->HasVolume();
198 m_state = S_TOP_CONFIGURED_IDLE;
199 m_extTimeout = 10000;
200 msg->Reply(CSinkControlProtocol::ACC, &reply, sizeof(SinkReply));
204 m_state = S_TOP_UNCONFIGURED;
205 msg->Reply(CSinkControlProtocol::ERR);
209 case CSinkControlProtocol::UNCONFIGURE:
214 m_sink->Deinitialize();
218 m_state = S_TOP_UNCONFIGURED;
219 msg->Reply(CSinkControlProtocol::ACC);
222 case CSinkControlProtocol::FLUSH:
224 msg->Reply(CSinkControlProtocol::ACC);
227 case CSinkControlProtocol::APPFOCUSED:
228 m_extAppFocused = *(bool*)msg->data;
237 else if (port == &m_dataPort)
241 case CSinkDataProtocol::DRAIN:
242 msg->Reply(CSinkDataProtocol::ACC);
243 m_state = S_TOP_UNCONFIGURED;
251 std::string portName = port == NULL ? "timer" : port->portName;
252 CLog::Log(LOGWARNING, "CActiveAESink::%s - signal: %d form port: %s not handled for state: %d", __FUNCTION__, signal, portName.c_str(), m_state);
256 case S_TOP_UNCONFIGURED:
257 if (port == NULL) // timeout
261 case CSinkControlProtocol::TIMEOUT:
268 else if (port == &m_dataPort)
272 case CSinkDataProtocol::SAMPLE:
273 CSampleBuffer *samples;
275 samples = *((CSampleBuffer**)msg->data);
276 timeout = 1000*samples->pkt->nb_samples/samples->pkt->config.sample_rate;
278 msg->Reply(CSinkDataProtocol::RETURNSAMPLE, &samples, sizeof(CSampleBuffer*));
287 case S_TOP_CONFIGURED:
288 if (port == &m_controlPort)
292 case CSinkControlProtocol::STREAMING:
293 m_extStreaming = *(bool*)msg->data;
295 if (!m_extSilenceTimer.IsTimePast())
297 m_state = S_TOP_CONFIGURED_SILENCE;
301 case CSinkControlProtocol::VOLUME:
302 m_volume = *(float*)msg->data;
303 m_sink->SetVolume(m_volume);
309 else if (port == &m_dataPort)
313 case CSinkDataProtocol::DRAIN:
315 msg->Reply(CSinkDataProtocol::ACC);
316 m_state = S_TOP_CONFIGURED_IDLE;
317 m_extTimeout = 10000;
319 case CSinkDataProtocol::SAMPLE:
320 CSampleBuffer *samples;
322 samples = *((CSampleBuffer**)msg->data);
323 delay = OutputSamples(samples);
324 msg->Reply(CSinkDataProtocol::RETURNSAMPLE, &samples, sizeof(CSampleBuffer*));
327 m_sink->Deinitialize();
330 m_state = S_TOP_CONFIGURED_SUSPEND;
335 m_state = S_TOP_CONFIGURED_PLAY;
336 m_extTimeout = delay / 2;
337 m_extSilenceTimer.Set(m_extSilenceTimeout);
346 case S_TOP_CONFIGURED_SUSPEND:
347 if (port == &m_controlPort)
351 case CSinkControlProtocol::STREAMING:
352 m_extStreaming = *(bool*)msg->data;
356 case CSinkControlProtocol::VOLUME:
357 m_volume = *(float*)msg->data;
363 else if (port == &m_dataPort)
367 case CSinkDataProtocol::SAMPLE:
370 OutputSamples(&m_sampleOfSilence);
371 m_state = S_TOP_CONFIGURED_PLAY;
373 m_bStateMachineSelfTrigger = true;
375 case CSinkDataProtocol::DRAIN:
376 msg->Reply(CSinkDataProtocol::ACC);
382 else if (port == NULL) // timeout
386 case CSinkControlProtocol::TIMEOUT:
387 m_extTimeout = 10000;
395 case S_TOP_CONFIGURED_IDLE:
396 if (port == &m_dataPort)
400 case CSinkDataProtocol::SAMPLE:
401 OutputSamples(&m_sampleOfSilence);
402 m_state = S_TOP_CONFIGURED_PLAY;
404 m_bStateMachineSelfTrigger = true;
410 else if (port == NULL) // timeout
414 case CSinkControlProtocol::TIMEOUT:
415 m_sink->Deinitialize();
418 m_state = S_TOP_CONFIGURED_SUSPEND;
419 m_extTimeout = 10000;
427 case S_TOP_CONFIGURED_PLAY:
428 if (port == NULL) // timeout
432 case CSinkControlProtocol::TIMEOUT:
433 if (!m_extSilenceTimer.IsTimePast())
435 m_state = S_TOP_CONFIGURED_SILENCE;
441 m_state = S_TOP_CONFIGURED_IDLE;
443 m_extTimeout = 10000;
454 case S_TOP_CONFIGURED_SILENCE:
455 if (port == NULL) // timeout
459 case CSinkControlProtocol::TIMEOUT:
460 OutputSamples(&m_sampleOfSilence);
463 m_sink->Deinitialize();
466 m_state = S_TOP_CONFIGURED_SUSPEND;
469 m_state = S_TOP_CONFIGURED_PLAY;
478 default: // we are in no state, should not happen
479 CLog::Log(LOGERROR, "CActiveAESink::%s - no valid state: %d", __FUNCTION__, m_state);
485 void CActiveAESink::Process()
488 Protocol *port = NULL;
490 XbmcThreads::EndTime timer;
492 m_state = S_TOP_UNCONFIGURED;
494 m_bStateMachineSelfTrigger = false;
495 m_extAppFocused = true;
500 timer.Set(m_extTimeout);
502 if (m_bStateMachineSelfTrigger)
504 m_bStateMachineSelfTrigger = false;
505 // self trigger state machine
506 StateMachine(msg->signal, port, msg);
507 if (!m_bStateMachineSelfTrigger)
514 // check control port
515 else if (m_controlPort.ReceiveOutMessage(&msg))
518 port = &m_controlPort;
521 else if (m_dataPort.ReceiveOutMessage(&msg))
529 StateMachine(msg->signal, port, msg);
530 if (!m_bStateMachineSelfTrigger)
539 else if (m_outMsgEvent.WaitMSec(m_extTimeout))
541 m_extTimeout = timer.MillisLeft();
547 msg = m_controlPort.GetMessage();
548 msg->signal = CSinkControlProtocol::TIMEOUT;
550 // signal timeout to state machine
551 StateMachine(msg->signal, port, msg);
552 if (!m_bStateMachineSelfTrigger)
561 void CActiveAESink::EnumerateSinkList(bool force)
563 if (!m_sinkInfoList.empty() && !force)
566 unsigned int c_retry = 4;
567 m_sinkInfoList.clear();
568 CAESinkFactory::EnumerateEx(m_sinkInfoList);
569 while(m_sinkInfoList.size() == 0 && c_retry > 0)
571 CLog::Log(LOGNOTICE, "No Devices found - retry: %d", c_retry);
574 // retry the enumeration
575 CAESinkFactory::EnumerateEx(m_sinkInfoList, true);
577 CLog::Log(LOGNOTICE, "Found %lu Lists of Devices", m_sinkInfoList.size());
581 void CActiveAESink::PrintSinks()
583 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
585 CLog::Log(LOGNOTICE, "Enumerated %s devices:", itt->m_sinkName.c_str());
587 for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2)
589 CLog::Log(LOGNOTICE, " Device %d", ++count);
590 CAEDeviceInfo& info = *itt2;
591 std::stringstream ss((std::string)info);
593 while(std::getline(ss, line, '\n'))
594 CLog::Log(LOGNOTICE, " %s", line.c_str());
599 void CActiveAESink::EnumerateOutputDevices(AEDeviceList &devices, bool passthrough)
601 EnumerateSinkList(false);
603 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
605 AESinkInfo sinkInfo = *itt;
606 for (AEDeviceInfoList::iterator itt2 = sinkInfo.m_deviceInfoList.begin(); itt2 != sinkInfo.m_deviceInfoList.end(); ++itt2)
608 CAEDeviceInfo devInfo = *itt2;
609 if (passthrough && devInfo.m_deviceType == AE_DEVTYPE_PCM)
612 std::string device = sinkInfo.m_sinkName + ":" + devInfo.m_deviceName;
614 std::stringstream ss;
616 /* add the sink name if we have more then one sink type */
617 if (m_sinkInfoList.size() > 1)
618 ss << sinkInfo.m_sinkName << ": ";
620 ss << devInfo.m_displayName;
621 if (!devInfo.m_displayNameExtra.empty())
622 ss << ", " << devInfo.m_displayNameExtra;
624 devices.push_back(AEDevice(ss.str(), device));
629 std::string CActiveAESink::GetDefaultDevice(bool passthrough)
631 EnumerateSinkList(false);
633 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
635 AESinkInfo sinkInfo = *itt;
636 for (AEDeviceInfoList::iterator itt2 = sinkInfo.m_deviceInfoList.begin(); itt2 != sinkInfo.m_deviceInfoList.end(); ++itt2)
638 CAEDeviceInfo devInfo = *itt2;
639 if (passthrough && devInfo.m_deviceType == AE_DEVTYPE_PCM)
642 std::string device = sinkInfo.m_sinkName + ":" + devInfo.m_deviceName;
649 void CActiveAESink::GetDeviceFriendlyName(std::string &device)
651 m_deviceFriendlyName = "Device not found";
652 /* Match the device and find its friendly name */
653 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
655 AESinkInfo sinkInfo = *itt;
656 for (AEDeviceInfoList::iterator itt2 = sinkInfo.m_deviceInfoList.begin(); itt2 != sinkInfo.m_deviceInfoList.end(); ++itt2)
658 CAEDeviceInfo& devInfo = *itt2;
659 if (devInfo.m_deviceName == device)
661 m_deviceFriendlyName = devInfo.m_displayName;
669 void CActiveAESink::OpenSink()
671 // we need a copy of m_device here because ParseDevice and CreateDevice write back
672 // into this variable
673 std::string device = m_device;
675 bool passthrough = AE_IS_RAW(m_requestedFormat.m_dataFormat);
677 CAESinkFactory::ParseDevice(device, driver);
678 if (driver.empty() && m_sink)
679 driver = m_sink->GetName();
681 CLog::Log(LOGINFO, "CActiveAESink::OpenSink - initialize sink");
686 m_sink->Deinitialize();
691 // get the display name of the device
692 GetDeviceFriendlyName(device);
694 // if we already have a driver, prepend it to the device string
696 device = driver + ":" + device;
698 // WARNING: this changes format and does not use passthrough
699 m_sinkFormat = m_requestedFormat;
700 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - trying to open device %s", device.c_str());
701 m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
703 // try first device in out list
704 if (!m_sink && !m_sinkInfoList.empty())
706 driver = m_sinkInfoList.front().m_sinkName;
707 device = m_sinkInfoList.front().m_deviceInfoList.front().m_deviceName;
708 GetDeviceFriendlyName(device);
710 device = driver + ":" + device;
711 m_sinkFormat = m_requestedFormat;
712 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - trying to open device %s", device.c_str());
713 m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
717 // TODO: should not be required by ActiveAE
720 device = "NULL:NULL";
721 m_sinkFormat = m_requestedFormat;
722 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - open NULL sink");
723 m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
728 CLog::Log(LOGERROR, "CActiveAESink::OpenSink - no sink was returned");
733 m_sink->SetVolume(m_volume);
735 #ifdef WORDS_BIGENDIAN
736 if (m_sinkFormat.m_dataFormat == AE_FMT_S16BE)
737 m_sinkFormat.m_dataFormat = AE_FMT_S16NE;
738 else if (m_sinkFormat.m_dataFormat == AE_FMT_S32BE)
739 m_sinkFormat.m_dataFormat = AE_FMT_S32NE;
741 if (m_sinkFormat.m_dataFormat == AE_FMT_S16LE)
742 m_sinkFormat.m_dataFormat = AE_FMT_S16NE;
743 else if (m_sinkFormat.m_dataFormat == AE_FMT_S32LE)
744 m_sinkFormat.m_dataFormat = AE_FMT_S32NE;
747 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - %s Initialized:", m_sink->GetName());
748 CLog::Log(LOGDEBUG, " Output Device : %s", m_deviceFriendlyName.c_str());
749 CLog::Log(LOGDEBUG, " Sample Rate : %d", m_sinkFormat.m_sampleRate);
750 CLog::Log(LOGDEBUG, " Sample Format : %s", CAEUtil::DataFormatToStr(m_sinkFormat.m_dataFormat));
751 CLog::Log(LOGDEBUG, " Channel Count : %d", m_sinkFormat.m_channelLayout.Count());
752 CLog::Log(LOGDEBUG, " Channel Layout: %s", ((std::string)m_sinkFormat.m_channelLayout).c_str());
753 CLog::Log(LOGDEBUG, " Frames : %d", m_sinkFormat.m_frames);
754 CLog::Log(LOGDEBUG, " Frame Samples : %d", m_sinkFormat.m_frameSamples);
755 CLog::Log(LOGDEBUG, " Frame Size : %d", m_sinkFormat.m_frameSize);
757 // init sample of silence
759 config.fmt = CActiveAEResample::GetAVSampleFormat(m_sinkFormat.m_dataFormat);
760 config.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_sinkFormat.m_dataFormat);
761 config.channel_layout = CActiveAEResample::GetAVChannelLayout(m_sinkFormat.m_channelLayout);
762 config.channels = m_sinkFormat.m_channelLayout.Count();
763 config.sample_rate = m_sinkFormat.m_sampleRate;
765 // init sample of silence/noise
766 delete m_sampleOfSilence.pkt;
767 m_sampleOfSilence.pkt = new CSoundPacket(config, m_sinkFormat.m_frames);
768 m_sampleOfSilence.pkt->nb_samples = m_sampleOfSilence.pkt->max_nb_samples;
774 _aligned_free(m_convertBuffer);
775 m_convertBuffer = NULL;
778 m_convertState = CHECK_CONVERT;
781 void CActiveAESink::ReturnBuffers()
784 CSampleBuffer *samples;
785 while (m_dataPort.ReceiveOutMessage(&msg))
787 if (msg->signal == CSinkDataProtocol::SAMPLE)
789 samples = *((CSampleBuffer**)msg->data);
790 msg->Reply(CSinkDataProtocol::RETURNSAMPLE, &samples, sizeof(CSampleBuffer*));
795 unsigned int CActiveAESink::OutputSamples(CSampleBuffer* samples)
797 uint8_t *buffer = samples->pkt->data[0];
798 unsigned int frames = samples->pkt->nb_samples;
799 unsigned int maxFrames;
801 unsigned int written = 0;
802 double sinkDelay = 0.0;
804 switch(m_convertState)
809 EnsureConvertBuffer(samples);
810 buffer = Convert(samples);
813 Endian_Swap16_buf((uint16_t *)buffer, (uint16_t *)buffer, frames * samples->pkt->config.channels);
816 ConvertInit(samples);
817 if (m_convertState == NEED_CONVERT)
818 buffer = Convert(samples);
819 else if (m_convertState == NEED_BYTESWAP)
820 Endian_Swap16_buf((uint16_t *)buffer, (uint16_t *)buffer, frames * samples->pkt->config.channels);
828 maxFrames = std::min(frames, m_sinkFormat.m_frames);
829 written = m_sink->AddPackets(buffer, maxFrames, true, true);
832 Sleep(500*m_sinkFormat.m_frames/m_sinkFormat.m_sampleRate);
837 CLog::Log(LOGERROR, "CActiveAESink::OutputSamples - failed");
838 m_stats->UpdateSinkDelay(0, frames);
844 else if (written > maxFrames)
847 CLog::Log(LOGERROR, "CActiveAESink::OutputSamples - sink returned error");
848 m_stats->UpdateSinkDelay(0, samples->pool ? maxFrames : 0);
852 buffer += written*m_sinkFormat.m_frameSize;
853 sinkDelay = m_sink->GetDelay();
854 m_stats->UpdateSinkDelay(sinkDelay, samples->pool ? written : 0);
856 return sinkDelay*1000;
859 void CActiveAESink::ConvertInit(CSampleBuffer* samples)
861 if (CActiveAEResample::GetAESampleFormat(samples->pkt->config.fmt, samples->pkt->config.bits_per_sample) != m_sinkFormat.m_dataFormat)
863 m_convertFn = CAEConvert::FrFloat(m_sinkFormat.m_dataFormat);
865 _aligned_free(m_convertBuffer);
866 m_convertBufferSampleSize = samples->pkt->max_nb_samples;
867 m_convertBuffer = (uint8_t*)_aligned_malloc(samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize, 16);
868 memset(m_convertBuffer, 0, samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize);
869 m_convertState = NEED_CONVERT;
871 else if (AE_IS_RAW(m_requestedFormat.m_dataFormat) && CAEUtil::S16NeedsByteSwap(AE_FMT_S16NE, m_sinkFormat.m_dataFormat))
873 m_convertState = NEED_BYTESWAP;
876 m_convertState = SKIP_CONVERT;
879 void CActiveAESink::EnsureConvertBuffer(CSampleBuffer* samples)
881 if (!m_convertBuffer)
884 if (samples->pkt->max_nb_samples <= m_convertBufferSampleSize)
887 _aligned_free(m_convertBuffer);
888 m_convertBufferSampleSize = samples->pkt->max_nb_samples;
889 m_convertBuffer = (uint8_t*)_aligned_malloc(samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize, 16);
890 memset(m_convertBuffer, 0, samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize);
893 uint8_t* CActiveAESink::Convert(CSampleBuffer* samples)
895 m_convertFn((float*)samples->pkt->data[0], samples->pkt->nb_samples * samples->pkt->config.channels, m_convertBuffer);
896 return m_convertBuffer;
899 #define PI 3.1415926536f
901 void CActiveAESink::GenerateNoise()
903 int nb_floats = m_sinkFormat.m_frames*m_sinkFormat.m_channelLayout.Count();
904 float *noise = (float*)_aligned_malloc(nb_floats*sizeof(float), 16);
907 for(int i=0; i<nb_floats;i++)
911 R1 = (float) rand() / (float) RAND_MAX;
912 R2 = (float) rand() / (float) RAND_MAX;
916 noise[i] = (float) sqrt( -2.0f * log( R1 )) * cos( 2.0f * PI * R2 ) * 0.00001f;
919 AEDataFormat fmt = CActiveAEResample::GetAESampleFormat(m_sampleOfSilence.pkt->config.fmt, m_sampleOfSilence.pkt->config.bits_per_sample);
920 CAEConvert::AEConvertFrFn convertFn = CAEConvert::FrFloat(fmt);
921 convertFn(noise, nb_floats, m_sampleOfSilence.pkt->data[0]);
922 _aligned_free(noise);
925 void CActiveAESink::SetSilenceTimer()
928 m_extSilenceTimeout = XbmcThreads::EndTime::InfiniteValue;
929 else if (m_extAppFocused)
930 m_extSilenceTimeout = CSettings::Get().GetInt("audiooutput.streamsilence") * 60000;
932 m_extSilenceTimeout = 0;
933 m_extSilenceTimer.Set(m_extSilenceTimeout);