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)
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())
140 S_TOP_UNCONFIGURED, // 1
141 S_TOP_CONFIGURED, // 2
142 S_TOP_CONFIGURED_SUSPEND, // 3
143 S_TOP_CONFIGURED_IDLE, // 4
144 S_TOP_CONFIGURED_PLAY, // 5
145 S_TOP_CONFIGURED_SILENCE, // 6
148 int SINK_parentStates[] = {
150 0, //TOP_UNCONFIGURED
152 2, //TOP_CONFIGURED_SUSPEND
153 2, //TOP_CONFIGURED_IDLE
154 2, //TOP_CONFIGURED_PLAY
155 2, //TOP_CONFIGURED_SILENCE
158 void CActiveAESink::StateMachine(int signal, Protocol *port, Message *msg)
160 for (int state = m_state; ; state = SINK_parentStates[state])
165 if (port == &m_controlPort)
169 case CSinkControlProtocol::CONFIGURE:
171 data = (SinkConfig*)msg->data;
174 m_requestedFormat = data->format;
175 m_stats = data->stats;
176 m_device = *(data->device);
179 m_extSilenceTimer = 0;
186 reply.format = m_sinkFormat;
187 reply.cacheTotal = m_sink->GetCacheTotal();
188 reply.latency = m_sink->GetLatency();
189 reply.hasVolume = m_sink->HasVolume();
190 m_state = S_TOP_CONFIGURED_IDLE;
191 m_extTimeout = 10000;
192 msg->Reply(CSinkControlProtocol::ACC, &reply, sizeof(SinkReply));
196 m_state = S_TOP_UNCONFIGURED;
197 msg->Reply(CSinkControlProtocol::ERR);
201 case CSinkControlProtocol::UNCONFIGURE:
206 m_sink->Deinitialize();
210 m_state = S_TOP_UNCONFIGURED;
211 msg->Reply(CSinkControlProtocol::ACC);
214 case CSinkControlProtocol::FLUSH:
216 msg->Reply(CSinkControlProtocol::ACC);
223 else if (port == &m_dataPort)
227 case CSinkDataProtocol::DRAIN:
228 msg->Reply(CSinkDataProtocol::ACC);
229 m_state = S_TOP_UNCONFIGURED;
237 std::string portName = port == NULL ? "timer" : port->portName;
238 CLog::Log(LOGWARNING, "CActiveAESink::%s - signal: %d form port: %s not handled for state: %d", __FUNCTION__, signal, portName.c_str(), m_state);
242 case S_TOP_UNCONFIGURED:
243 if (port == NULL) // timeout
247 case CSinkControlProtocol::TIMEOUT:
254 else if (port == &m_dataPort)
258 case CSinkDataProtocol::SAMPLE:
259 CSampleBuffer *samples;
261 samples = *((CSampleBuffer**)msg->data);
262 timeout = 1000*samples->pkt->nb_samples/samples->pkt->config.sample_rate;
264 msg->Reply(CSinkDataProtocol::RETURNSAMPLE, &samples, sizeof(CSampleBuffer*));
273 case S_TOP_CONFIGURED:
274 if (port == &m_controlPort)
278 case CSinkControlProtocol::SILENCEMODE:
280 silencemode = *(bool*)msg->data;
282 m_extSilenceTimeout = XbmcThreads::EndTime::InfiniteValue;
284 m_extSilenceTimeout = CSettings::Get().GetInt("audiooutput.streamsilence") * 60000;
285 m_extSilenceTimer.Set(m_extSilenceTimeout);
286 if (!m_extSilenceTimer.IsTimePast())
288 m_state = S_TOP_CONFIGURED_SILENCE;
292 case CSinkControlProtocol::VOLUME:
293 m_volume = *(float*)msg->data;
294 m_sink->SetVolume(m_volume);
300 else if (port == &m_dataPort)
304 case CSinkDataProtocol::DRAIN:
306 msg->Reply(CSinkDataProtocol::ACC);
307 m_state = S_TOP_CONFIGURED_IDLE;
308 m_extTimeout = 10000;
310 case CSinkDataProtocol::SAMPLE:
311 CSampleBuffer *samples;
313 samples = *((CSampleBuffer**)msg->data);
314 delay = OutputSamples(samples);
315 msg->Reply(CSinkDataProtocol::RETURNSAMPLE, &samples, sizeof(CSampleBuffer*));
318 m_sink->Deinitialize();
321 m_state = S_TOP_CONFIGURED_SUSPEND;
326 m_state = S_TOP_CONFIGURED_PLAY;
327 m_extTimeout = delay / 2;
328 m_extSilenceTimer.Set(m_extSilenceTimeout);
337 case S_TOP_CONFIGURED_SUSPEND:
338 if (port == &m_controlPort)
342 case CSinkControlProtocol::SILENCEMODE:
344 case CSinkControlProtocol::VOLUME:
345 m_volume = *(float*)msg->data;
351 else if (port == &m_dataPort)
355 case CSinkDataProtocol::SAMPLE:
358 OutputSamples(&m_sampleOfSilence);
359 m_state = S_TOP_CONFIGURED_PLAY;
361 m_bStateMachineSelfTrigger = true;
363 case CSinkDataProtocol::DRAIN:
364 msg->Reply(CSinkDataProtocol::ACC);
370 else if (port == NULL) // timeout
374 case CSinkControlProtocol::TIMEOUT:
375 m_extTimeout = 10000;
383 case S_TOP_CONFIGURED_IDLE:
384 if (port == &m_dataPort)
388 case CSinkDataProtocol::SAMPLE:
389 OutputSamples(&m_sampleOfSilence);
390 m_state = S_TOP_CONFIGURED_PLAY;
392 m_bStateMachineSelfTrigger = true;
398 else if (port == NULL) // timeout
402 case CSinkControlProtocol::TIMEOUT:
403 m_sink->Deinitialize();
406 m_state = S_TOP_CONFIGURED_SUSPEND;
407 m_extTimeout = 10000;
415 case S_TOP_CONFIGURED_PLAY:
416 if (port == NULL) // timeout
420 case CSinkControlProtocol::TIMEOUT:
421 if (!m_extSilenceTimer.IsTimePast())
423 m_state = S_TOP_CONFIGURED_SILENCE;
429 m_state = S_TOP_CONFIGURED_IDLE;
430 m_extTimeout = 10000;
439 case S_TOP_CONFIGURED_SILENCE:
440 if (port == NULL) // timeout
444 case CSinkControlProtocol::TIMEOUT:
445 OutputSamples(&m_sampleOfSilence);
448 m_sink->Deinitialize();
451 m_state = S_TOP_CONFIGURED_SUSPEND;
454 m_state = S_TOP_CONFIGURED_PLAY;
463 default: // we are in no state, should not happen
464 CLog::Log(LOGERROR, "CActiveAESink::%s - no valid state: %d", __FUNCTION__, m_state);
470 void CActiveAESink::Process()
473 Protocol *port = NULL;
475 XbmcThreads::EndTime timer;
477 m_state = S_TOP_UNCONFIGURED;
479 m_bStateMachineSelfTrigger = false;
484 timer.Set(m_extTimeout);
486 if (m_bStateMachineSelfTrigger)
488 m_bStateMachineSelfTrigger = false;
489 // self trigger state machine
490 StateMachine(msg->signal, port, msg);
491 if (!m_bStateMachineSelfTrigger)
498 // check control port
499 else if (m_controlPort.ReceiveOutMessage(&msg))
502 port = &m_controlPort;
505 else if (m_dataPort.ReceiveOutMessage(&msg))
513 StateMachine(msg->signal, port, msg);
514 if (!m_bStateMachineSelfTrigger)
523 else if (m_outMsgEvent.WaitMSec(m_extTimeout))
525 m_extTimeout = timer.MillisLeft();
531 msg = m_controlPort.GetMessage();
532 msg->signal = CSinkControlProtocol::TIMEOUT;
534 // signal timeout to state machine
535 StateMachine(msg->signal, port, msg);
536 if (!m_bStateMachineSelfTrigger)
545 void CActiveAESink::EnumerateSinkList(bool force)
547 if (!m_sinkInfoList.empty() && !force)
550 unsigned int c_retry = 4;
551 m_sinkInfoList.clear();
552 CAESinkFactory::EnumerateEx(m_sinkInfoList);
553 while(m_sinkInfoList.size() == 0 && c_retry > 0)
555 CLog::Log(LOGNOTICE, "No Devices found - retry: %d", c_retry);
558 // retry the enumeration
559 CAESinkFactory::EnumerateEx(m_sinkInfoList, true);
561 CLog::Log(LOGNOTICE, "Found %lu Lists of Devices", m_sinkInfoList.size());
565 void CActiveAESink::PrintSinks()
567 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
569 CLog::Log(LOGNOTICE, "Enumerated %s devices:", itt->m_sinkName.c_str());
571 for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2)
573 CLog::Log(LOGNOTICE, " Device %d", ++count);
574 CAEDeviceInfo& info = *itt2;
575 std::stringstream ss((std::string)info);
577 while(std::getline(ss, line, '\n'))
578 CLog::Log(LOGNOTICE, " %s", line.c_str());
583 void CActiveAESink::EnumerateOutputDevices(AEDeviceList &devices, bool passthrough)
585 EnumerateSinkList(false);
587 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
589 AESinkInfo sinkInfo = *itt;
590 for (AEDeviceInfoList::iterator itt2 = sinkInfo.m_deviceInfoList.begin(); itt2 != sinkInfo.m_deviceInfoList.end(); ++itt2)
592 CAEDeviceInfo devInfo = *itt2;
593 if (passthrough && devInfo.m_deviceType == AE_DEVTYPE_PCM)
596 std::string device = sinkInfo.m_sinkName + ":" + devInfo.m_deviceName;
598 std::stringstream ss;
600 /* add the sink name if we have more then one sink type */
601 if (m_sinkInfoList.size() > 1)
602 ss << sinkInfo.m_sinkName << ": ";
604 ss << devInfo.m_displayName;
605 if (!devInfo.m_displayNameExtra.empty())
606 ss << ", " << devInfo.m_displayNameExtra;
608 devices.push_back(AEDevice(ss.str(), device));
613 std::string CActiveAESink::GetDefaultDevice(bool passthrough)
615 EnumerateSinkList(false);
617 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
619 AESinkInfo sinkInfo = *itt;
620 for (AEDeviceInfoList::iterator itt2 = sinkInfo.m_deviceInfoList.begin(); itt2 != sinkInfo.m_deviceInfoList.end(); ++itt2)
622 CAEDeviceInfo devInfo = *itt2;
623 if (passthrough && devInfo.m_deviceType == AE_DEVTYPE_PCM)
626 std::string device = sinkInfo.m_sinkName + ":" + devInfo.m_deviceName;
633 void CActiveAESink::GetDeviceFriendlyName(std::string &device)
635 m_deviceFriendlyName = "Device not found";
636 /* Match the device and find its friendly name */
637 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
639 AESinkInfo sinkInfo = *itt;
640 for (AEDeviceInfoList::iterator itt2 = sinkInfo.m_deviceInfoList.begin(); itt2 != sinkInfo.m_deviceInfoList.end(); ++itt2)
642 CAEDeviceInfo& devInfo = *itt2;
643 if (devInfo.m_deviceName == device)
645 m_deviceFriendlyName = devInfo.m_displayName;
653 void CActiveAESink::OpenSink()
655 // we need a copy of m_device here because ParseDevice and CreateDevice write back
656 // into this variable
657 std::string device = m_device;
659 bool passthrough = AE_IS_RAW(m_requestedFormat.m_dataFormat);
661 CAESinkFactory::ParseDevice(device, driver);
662 if (driver.empty() && m_sink)
663 driver = m_sink->GetName();
665 CLog::Log(LOGINFO, "CActiveAESink::OpenSink - initialize sink");
670 m_sink->Deinitialize();
675 // get the display name of the device
676 GetDeviceFriendlyName(device);
678 // if we already have a driver, prepend it to the device string
680 device = driver + ":" + device;
682 // WARNING: this changes format and does not use passthrough
683 m_sinkFormat = m_requestedFormat;
684 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - trying to open device %s", device.c_str());
685 m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
687 // try first device in out list
688 if (!m_sink && !m_sinkInfoList.empty())
690 driver = m_sinkInfoList.front().m_sinkName;
691 device = m_sinkInfoList.front().m_deviceInfoList.front().m_deviceName;
692 GetDeviceFriendlyName(device);
694 device = driver + ":" + device;
695 m_sinkFormat = m_requestedFormat;
696 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - trying to open device %s", device.c_str());
697 m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
701 // TODO: should not be required by ActiveAE
704 device = "NULL:NULL";
705 m_sinkFormat = m_requestedFormat;
706 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - open NULL sink");
707 m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
712 CLog::Log(LOGERROR, "CActiveAESink::OpenSink - no sink was returned");
717 m_sink->SetVolume(m_volume);
719 #ifdef WORDS_BIGENDIAN
720 if (m_sinkFormat.m_dataFormat == AE_FMT_S16BE)
721 m_sinkFormat.m_dataFormat = AE_FMT_S16NE;
722 else if (m_sinkFormat.m_dataFormat == AE_FMT_S32BE)
723 m_sinkFormat.m_dataFormat = AE_FMT_S32NE;
725 if (m_sinkFormat.m_dataFormat == AE_FMT_S16LE)
726 m_sinkFormat.m_dataFormat = AE_FMT_S16NE;
727 else if (m_sinkFormat.m_dataFormat == AE_FMT_S32LE)
728 m_sinkFormat.m_dataFormat = AE_FMT_S32NE;
731 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - %s Initialized:", m_sink->GetName());
732 CLog::Log(LOGDEBUG, " Output Device : %s", m_deviceFriendlyName.c_str());
733 CLog::Log(LOGDEBUG, " Sample Rate : %d", m_sinkFormat.m_sampleRate);
734 CLog::Log(LOGDEBUG, " Sample Format : %s", CAEUtil::DataFormatToStr(m_sinkFormat.m_dataFormat));
735 CLog::Log(LOGDEBUG, " Channel Count : %d", m_sinkFormat.m_channelLayout.Count());
736 CLog::Log(LOGDEBUG, " Channel Layout: %s", ((std::string)m_sinkFormat.m_channelLayout).c_str());
737 CLog::Log(LOGDEBUG, " Frames : %d", m_sinkFormat.m_frames);
738 CLog::Log(LOGDEBUG, " Frame Samples : %d", m_sinkFormat.m_frameSamples);
739 CLog::Log(LOGDEBUG, " Frame Size : %d", m_sinkFormat.m_frameSize);
741 // init sample of silence
743 config.fmt = CActiveAEResample::GetAVSampleFormat(m_sinkFormat.m_dataFormat);
744 config.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_sinkFormat.m_dataFormat);
745 config.channel_layout = CActiveAEResample::GetAVChannelLayout(m_sinkFormat.m_channelLayout);
746 config.channels = m_sinkFormat.m_channelLayout.Count();
747 config.sample_rate = m_sinkFormat.m_sampleRate;
749 // init sample of silence/noise
750 delete m_sampleOfSilence.pkt;
751 m_sampleOfSilence.pkt = new CSoundPacket(config, m_sinkFormat.m_frames);
752 m_sampleOfSilence.pkt->nb_samples = m_sampleOfSilence.pkt->max_nb_samples;
758 _aligned_free(m_convertBuffer);
759 m_convertBuffer = NULL;
762 m_convertState = CHECK_CONVERT;
765 void CActiveAESink::ReturnBuffers()
768 CSampleBuffer *samples;
769 while (m_dataPort.ReceiveOutMessage(&msg))
771 if (msg->signal == CSinkDataProtocol::SAMPLE)
773 samples = *((CSampleBuffer**)msg->data);
774 msg->Reply(CSinkDataProtocol::RETURNSAMPLE, &samples, sizeof(CSampleBuffer*));
779 unsigned int CActiveAESink::OutputSamples(CSampleBuffer* samples)
781 uint8_t *buffer = samples->pkt->data[0];
782 unsigned int frames = samples->pkt->nb_samples;
783 unsigned int maxFrames;
785 unsigned int written = 0;
786 double sinkDelay = 0.0;
788 switch(m_convertState)
793 EnsureConvertBuffer(samples);
794 buffer = Convert(samples);
797 Endian_Swap16_buf((uint16_t *)buffer, (uint16_t *)buffer, frames * samples->pkt->config.channels);
800 ConvertInit(samples);
801 if (m_convertState == NEED_CONVERT)
802 buffer = Convert(samples);
803 else if (m_convertState == NEED_BYTESWAP)
804 Endian_Swap16_buf((uint16_t *)buffer, (uint16_t *)buffer, frames * samples->pkt->config.channels);
812 maxFrames = std::min(frames, m_sinkFormat.m_frames);
813 written = m_sink->AddPackets(buffer, maxFrames, true, true);
816 Sleep(500*m_sinkFormat.m_frames/m_sinkFormat.m_sampleRate);
821 CLog::Log(LOGERROR, "CActiveAESink::OutputSamples - failed");
822 m_stats->UpdateSinkDelay(0, frames);
828 else if (written > maxFrames)
831 CLog::Log(LOGERROR, "CActiveAESink::OutputSamples - sink returned error");
832 m_stats->UpdateSinkDelay(0, samples->pool ? maxFrames : 0);
836 buffer += written*m_sinkFormat.m_frameSize;
837 sinkDelay = m_sink->GetDelay();
838 m_stats->UpdateSinkDelay(sinkDelay, samples->pool ? written : 0);
840 return sinkDelay*1000;
843 void CActiveAESink::ConvertInit(CSampleBuffer* samples)
845 if (CActiveAEResample::GetAESampleFormat(samples->pkt->config.fmt, samples->pkt->config.bits_per_sample) != m_sinkFormat.m_dataFormat)
847 m_convertFn = CAEConvert::FrFloat(m_sinkFormat.m_dataFormat);
849 _aligned_free(m_convertBuffer);
850 m_convertBufferSampleSize = samples->pkt->max_nb_samples;
851 m_convertBuffer = (uint8_t*)_aligned_malloc(samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize, 16);
852 memset(m_convertBuffer, 0, samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize);
853 m_convertState = NEED_CONVERT;
855 else if (AE_IS_RAW(m_requestedFormat.m_dataFormat) && CAEUtil::S16NeedsByteSwap(AE_FMT_S16NE, m_sinkFormat.m_dataFormat))
857 m_convertState = NEED_BYTESWAP;
860 m_convertState = SKIP_CONVERT;
863 void CActiveAESink::EnsureConvertBuffer(CSampleBuffer* samples)
865 if (!m_convertBuffer)
868 if (samples->pkt->max_nb_samples <= m_convertBufferSampleSize)
871 _aligned_free(m_convertBuffer);
872 m_convertBufferSampleSize = samples->pkt->max_nb_samples;
873 m_convertBuffer = (uint8_t*)_aligned_malloc(samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize, 16);
874 memset(m_convertBuffer, 0, samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize);
877 uint8_t* CActiveAESink::Convert(CSampleBuffer* samples)
879 m_convertFn((float*)samples->pkt->data[0], samples->pkt->nb_samples * samples->pkt->config.channels, m_convertBuffer);
880 return m_convertBuffer;
883 #define PI 3.1415926536f
885 void CActiveAESink::GenerateNoise()
887 int nb_floats = m_sinkFormat.m_frames*m_sinkFormat.m_channelLayout.Count();
888 float *noise = (float*)_aligned_malloc(nb_floats*sizeof(float), 16);
891 for(int i=0; i<nb_floats;i++)
895 R1 = (float) rand() / (float) RAND_MAX;
896 R2 = (float) rand() / (float) RAND_MAX;
900 noise[i] = (float) sqrt( -2.0f * log( R1 )) * cos( 2.0f * PI * R2 ) * 0.00001f;
903 AEDataFormat fmt = CActiveAEResample::GetAESampleFormat(m_sampleOfSilence.pkt->config.fmt, m_sampleOfSilence.pkt->config.bits_per_sample);
904 CAEConvert::AEConvertFrFn convertFn = CAEConvert::FrFloat(fmt);
905 convertFn(noise, nb_floats, m_sampleOfSilence.pkt->data[0]);
906 _aligned_free(noise);