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 for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2)
119 CAEDeviceInfo& info = *itt2;
120 if (info.m_deviceName == dev)
122 AEDataFormatList::iterator itt3;
123 itt3 = find(info.m_dataFormats.begin(), info.m_dataFormats.end(), format);
124 if (itt3 != info.m_dataFormats.end())
137 S_TOP_UNCONFIGURED, // 1
138 S_TOP_CONFIGURED, // 2
139 S_TOP_CONFIGURED_SUSPEND, // 3
140 S_TOP_CONFIGURED_IDLE, // 4
141 S_TOP_CONFIGURED_PLAY, // 5
142 S_TOP_CONFIGURED_SILENCE, // 6
145 int SINK_parentStates[] = {
147 0, //TOP_UNCONFIGURED
149 2, //TOP_CONFIGURED_SUSPEND
150 2, //TOP_CONFIGURED_IDLE
151 2, //TOP_CONFIGURED_PLAY
152 2, //TOP_CONFIGURED_SILENCE
155 void CActiveAESink::StateMachine(int signal, Protocol *port, Message *msg)
157 for (int state = m_state; ; state = SINK_parentStates[state])
162 if (port == &m_controlPort)
166 case CSinkControlProtocol::CONFIGURE:
168 data = (SinkConfig*)msg->data;
171 m_requestedFormat = data->format;
172 m_stats = data->stats;
173 m_device = *(data->device);
176 m_extSilenceTimer = 0;
183 reply.format = m_sinkFormat;
184 reply.cacheTotal = m_sink->GetCacheTotal();
185 reply.latency = m_sink->GetLatency();
186 reply.hasVolume = m_sink->HasVolume();
187 m_state = S_TOP_CONFIGURED_IDLE;
188 m_extTimeout = 10000;
189 msg->Reply(CSinkControlProtocol::ACC, &reply, sizeof(SinkReply));
193 m_state = S_TOP_UNCONFIGURED;
194 msg->Reply(CSinkControlProtocol::ERR);
198 case CSinkControlProtocol::UNCONFIGURE:
203 m_sink->Deinitialize();
207 m_state = S_TOP_UNCONFIGURED;
208 msg->Reply(CSinkControlProtocol::ACC);
211 case CSinkControlProtocol::FLUSH:
213 msg->Reply(CSinkControlProtocol::ACC);
220 else if (port == &m_dataPort)
224 case CSinkDataProtocol::DRAIN:
225 msg->Reply(CSinkDataProtocol::ACC);
226 m_state = S_TOP_UNCONFIGURED;
234 std::string portName = port == NULL ? "timer" : port->portName;
235 CLog::Log(LOGWARNING, "CActiveAESink::%s - signal: %d form port: %s not handled for state: %d", __FUNCTION__, signal, portName.c_str(), m_state);
239 case S_TOP_UNCONFIGURED:
240 if (port == NULL) // timeout
244 case CSinkControlProtocol::TIMEOUT:
251 else if (port == &m_dataPort)
255 case CSinkDataProtocol::SAMPLE:
256 CSampleBuffer *samples;
258 samples = *((CSampleBuffer**)msg->data);
259 timeout = 1000*samples->pkt->nb_samples/samples->pkt->config.sample_rate;
261 msg->Reply(CSinkDataProtocol::RETURNSAMPLE, &samples, sizeof(CSampleBuffer*));
270 case S_TOP_CONFIGURED:
271 if (port == &m_controlPort)
275 case CSinkControlProtocol::SILENCEMODE:
277 silencemode = *(bool*)msg->data;
279 m_extSilenceTimeout = XbmcThreads::EndTime::InfiniteValue;
281 m_extSilenceTimeout = CSettings::Get().GetInt("audiooutput.streamsilence") * 60000;
282 m_extSilenceTimer.Set(m_extSilenceTimeout);
283 if (!m_extSilenceTimer.IsTimePast())
285 m_state = S_TOP_CONFIGURED_SILENCE;
289 case CSinkControlProtocol::VOLUME:
290 m_volume = *(float*)msg->data;
291 m_sink->SetVolume(m_volume);
297 else if (port == &m_dataPort)
301 case CSinkDataProtocol::DRAIN:
303 msg->Reply(CSinkDataProtocol::ACC);
304 m_state = S_TOP_CONFIGURED_IDLE;
305 m_extTimeout = 10000;
307 case CSinkDataProtocol::SAMPLE:
308 CSampleBuffer *samples;
310 samples = *((CSampleBuffer**)msg->data);
311 delay = OutputSamples(samples);
312 msg->Reply(CSinkDataProtocol::RETURNSAMPLE, &samples, sizeof(CSampleBuffer*));
315 m_sink->Deinitialize();
318 m_state = S_TOP_CONFIGURED_SUSPEND;
323 m_state = S_TOP_CONFIGURED_PLAY;
324 m_extTimeout = delay / 2;
325 m_extSilenceTimer.Set(m_extSilenceTimeout);
334 case S_TOP_CONFIGURED_SUSPEND:
335 if (port == &m_controlPort)
339 case CSinkControlProtocol::SILENCEMODE:
341 case CSinkControlProtocol::VOLUME:
342 m_volume = *(float*)msg->data;
348 else if (port == &m_dataPort)
352 case CSinkDataProtocol::SAMPLE:
355 OutputSamples(&m_sampleOfSilence);
356 m_state = S_TOP_CONFIGURED_PLAY;
358 m_bStateMachineSelfTrigger = true;
360 case CSinkDataProtocol::DRAIN:
361 msg->Reply(CSinkDataProtocol::ACC);
367 else if (port == NULL) // timeout
371 case CSinkControlProtocol::TIMEOUT:
372 m_extTimeout = 10000;
380 case S_TOP_CONFIGURED_IDLE:
381 if (port == &m_dataPort)
385 case CSinkDataProtocol::SAMPLE:
386 OutputSamples(&m_sampleOfSilence);
387 m_state = S_TOP_CONFIGURED_PLAY;
389 m_bStateMachineSelfTrigger = true;
395 else if (port == NULL) // timeout
399 case CSinkControlProtocol::TIMEOUT:
400 m_sink->Deinitialize();
403 m_state = S_TOP_CONFIGURED_SUSPEND;
404 m_extTimeout = 10000;
412 case S_TOP_CONFIGURED_PLAY:
413 if (port == NULL) // timeout
417 case CSinkControlProtocol::TIMEOUT:
418 if (!m_extSilenceTimer.IsTimePast())
420 m_state = S_TOP_CONFIGURED_SILENCE;
426 m_state = S_TOP_CONFIGURED_IDLE;
427 m_extTimeout = 10000;
436 case S_TOP_CONFIGURED_SILENCE:
437 if (port == NULL) // timeout
441 case CSinkControlProtocol::TIMEOUT:
442 OutputSamples(&m_sampleOfSilence);
445 m_sink->Deinitialize();
448 m_state = S_TOP_CONFIGURED_SUSPEND;
451 m_state = S_TOP_CONFIGURED_PLAY;
460 default: // we are in no state, should not happen
461 CLog::Log(LOGERROR, "CActiveAESink::%s - no valid state: %d", __FUNCTION__, m_state);
467 void CActiveAESink::Process()
470 Protocol *port = NULL;
472 XbmcThreads::EndTime timer;
474 m_state = S_TOP_UNCONFIGURED;
476 m_bStateMachineSelfTrigger = false;
481 timer.Set(m_extTimeout);
483 if (m_bStateMachineSelfTrigger)
485 m_bStateMachineSelfTrigger = false;
486 // self trigger state machine
487 StateMachine(msg->signal, port, msg);
488 if (!m_bStateMachineSelfTrigger)
495 // check control port
496 else if (m_controlPort.ReceiveOutMessage(&msg))
499 port = &m_controlPort;
502 else if (m_dataPort.ReceiveOutMessage(&msg))
510 StateMachine(msg->signal, port, msg);
511 if (!m_bStateMachineSelfTrigger)
520 else if (m_outMsgEvent.WaitMSec(m_extTimeout))
522 m_extTimeout = timer.MillisLeft();
528 msg = m_controlPort.GetMessage();
529 msg->signal = CSinkControlProtocol::TIMEOUT;
531 // signal timeout to state machine
532 StateMachine(msg->signal, port, msg);
533 if (!m_bStateMachineSelfTrigger)
542 void CActiveAESink::EnumerateSinkList(bool force)
544 if (!m_sinkInfoList.empty() && !force)
547 unsigned int c_retry = 5;
548 m_sinkInfoList.clear();
549 CAESinkFactory::EnumerateEx(m_sinkInfoList);
550 while(m_sinkInfoList.size() == 0 && c_retry > 0)
552 CLog::Log(LOGNOTICE, "No Devices found - retry: %d", c_retry);
555 // retry the enumeration
556 CAESinkFactory::EnumerateEx(m_sinkInfoList, true);
558 CLog::Log(LOGNOTICE, "Found %lu Lists of Devices", m_sinkInfoList.size());
562 void CActiveAESink::PrintSinks()
564 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
566 CLog::Log(LOGNOTICE, "Enumerated %s devices:", itt->m_sinkName.c_str());
568 for (AEDeviceInfoList::iterator itt2 = itt->m_deviceInfoList.begin(); itt2 != itt->m_deviceInfoList.end(); ++itt2)
570 CLog::Log(LOGNOTICE, " Device %d", ++count);
571 CAEDeviceInfo& info = *itt2;
572 std::stringstream ss((std::string)info);
574 while(std::getline(ss, line, '\n'))
575 CLog::Log(LOGNOTICE, " %s", line.c_str());
580 void CActiveAESink::EnumerateOutputDevices(AEDeviceList &devices, bool passthrough)
582 EnumerateSinkList(false);
584 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
586 AESinkInfo sinkInfo = *itt;
587 for (AEDeviceInfoList::iterator itt2 = sinkInfo.m_deviceInfoList.begin(); itt2 != sinkInfo.m_deviceInfoList.end(); ++itt2)
589 CAEDeviceInfo devInfo = *itt2;
590 if (passthrough && devInfo.m_deviceType == AE_DEVTYPE_PCM)
593 std::string device = sinkInfo.m_sinkName + ":" + devInfo.m_deviceName;
595 std::stringstream ss;
597 /* add the sink name if we have more then one sink type */
598 if (m_sinkInfoList.size() > 1)
599 ss << sinkInfo.m_sinkName << ": ";
601 ss << devInfo.m_displayName;
602 if (!devInfo.m_displayNameExtra.empty())
603 ss << ", " << devInfo.m_displayNameExtra;
605 devices.push_back(AEDevice(ss.str(), device));
610 std::string CActiveAESink::GetDefaultDevice(bool passthrough)
612 EnumerateSinkList(false);
614 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
616 AESinkInfo sinkInfo = *itt;
617 for (AEDeviceInfoList::iterator itt2 = sinkInfo.m_deviceInfoList.begin(); itt2 != sinkInfo.m_deviceInfoList.end(); ++itt2)
619 CAEDeviceInfo devInfo = *itt2;
620 if (passthrough && devInfo.m_deviceType == AE_DEVTYPE_PCM)
623 std::string device = sinkInfo.m_sinkName + ":" + devInfo.m_deviceName;
630 void CActiveAESink::GetDeviceFriendlyName(std::string &device)
632 m_deviceFriendlyName = "Device not found";
633 /* Match the device and find its friendly name */
634 for (AESinkInfoList::iterator itt = m_sinkInfoList.begin(); itt != m_sinkInfoList.end(); ++itt)
636 AESinkInfo sinkInfo = *itt;
637 for (AEDeviceInfoList::iterator itt2 = sinkInfo.m_deviceInfoList.begin(); itt2 != sinkInfo.m_deviceInfoList.end(); ++itt2)
639 CAEDeviceInfo& devInfo = *itt2;
640 if (devInfo.m_deviceName == device)
642 m_deviceFriendlyName = devInfo.m_displayName;
650 void CActiveAESink::OpenSink()
652 // we need a copy of m_device here because ParseDevice and CreateDevice write back
653 // into this variable
654 std::string device = m_device;
656 bool passthrough = AE_IS_RAW(m_requestedFormat.m_dataFormat);
658 CAESinkFactory::ParseDevice(device, driver);
659 if (driver.empty() && m_sink)
660 driver = m_sink->GetName();
662 CLog::Log(LOGINFO, "CActiveAESink::OpenSink - initialize sink");
667 m_sink->Deinitialize();
672 // get the display name of the device
673 GetDeviceFriendlyName(device);
675 // if we already have a driver, prepend it to the device string
677 device = driver + ":" + device;
679 // WARNING: this changes format and does not use passthrough
680 m_sinkFormat = m_requestedFormat;
681 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - trying to open device %s", device.c_str());
682 m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
684 // try first device in out list
685 if (!m_sink && !m_sinkInfoList.empty())
687 driver = m_sinkInfoList.front().m_sinkName;
688 device = m_sinkInfoList.front().m_deviceInfoList.front().m_deviceName;
689 GetDeviceFriendlyName(device);
691 device = driver + ":" + device;
692 m_sinkFormat = m_requestedFormat;
693 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - trying to open device %s", device.c_str());
694 m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
698 // TODO: should not be required by ActiveAE
701 device = "NULL:NULL";
702 m_sinkFormat = m_requestedFormat;
703 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - open NULL sink");
704 m_sink = CAESinkFactory::Create(device, m_sinkFormat, passthrough);
709 CLog::Log(LOGERROR, "CActiveAESink::OpenSink - no sink was returned");
714 m_sink->SetVolume(m_volume);
716 #ifdef WORDS_BIGENDIAN
717 if (m_sinkFormat.m_dataFormat == AE_FMT_S16BE)
718 m_sinkFormat.m_dataFormat = AE_FMT_S16NE;
719 else if (m_sinkFormat.m_dataFormat == AE_FMT_S32BE)
720 m_sinkFormat.m_dataFormat = AE_FMT_S32NE;
722 if (m_sinkFormat.m_dataFormat == AE_FMT_S16LE)
723 m_sinkFormat.m_dataFormat = AE_FMT_S16NE;
724 else if (m_sinkFormat.m_dataFormat == AE_FMT_S32LE)
725 m_sinkFormat.m_dataFormat = AE_FMT_S32NE;
728 CLog::Log(LOGDEBUG, "CActiveAESink::OpenSink - %s Initialized:", m_sink->GetName());
729 CLog::Log(LOGDEBUG, " Output Device : %s", m_deviceFriendlyName.c_str());
730 CLog::Log(LOGDEBUG, " Sample Rate : %d", m_sinkFormat.m_sampleRate);
731 CLog::Log(LOGDEBUG, " Sample Format : %s", CAEUtil::DataFormatToStr(m_sinkFormat.m_dataFormat));
732 CLog::Log(LOGDEBUG, " Channel Count : %d", m_sinkFormat.m_channelLayout.Count());
733 CLog::Log(LOGDEBUG, " Channel Layout: %s", ((std::string)m_sinkFormat.m_channelLayout).c_str());
734 CLog::Log(LOGDEBUG, " Frames : %d", m_sinkFormat.m_frames);
735 CLog::Log(LOGDEBUG, " Frame Samples : %d", m_sinkFormat.m_frameSamples);
736 CLog::Log(LOGDEBUG, " Frame Size : %d", m_sinkFormat.m_frameSize);
738 // init sample of silence
740 config.fmt = CActiveAEResample::GetAVSampleFormat(m_sinkFormat.m_dataFormat);
741 config.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_sinkFormat.m_dataFormat);
742 config.channel_layout = CActiveAEResample::GetAVChannelLayout(m_sinkFormat.m_channelLayout);
743 config.channels = m_sinkFormat.m_channelLayout.Count();
744 config.sample_rate = m_sinkFormat.m_sampleRate;
746 // init sample of silence/noise
747 delete m_sampleOfSilence.pkt;
748 m_sampleOfSilence.pkt = new CSoundPacket(config, m_sinkFormat.m_frames);
749 m_sampleOfSilence.pkt->nb_samples = m_sampleOfSilence.pkt->max_nb_samples;
755 _aligned_free(m_convertBuffer);
756 m_convertBuffer = NULL;
759 m_convertState = CHECK_CONVERT;
762 void CActiveAESink::ReturnBuffers()
765 CSampleBuffer *samples;
766 while (m_dataPort.ReceiveOutMessage(&msg))
768 if (msg->signal == CSinkDataProtocol::SAMPLE)
770 samples = *((CSampleBuffer**)msg->data);
771 msg->Reply(CSinkDataProtocol::RETURNSAMPLE, &samples, sizeof(CSampleBuffer*));
776 unsigned int CActiveAESink::OutputSamples(CSampleBuffer* samples)
778 uint8_t *buffer = samples->pkt->data[0];
779 unsigned int frames = samples->pkt->nb_samples;
780 unsigned int maxFrames;
782 unsigned int written = 0;
783 double sinkDelay = 0.0;
785 switch(m_convertState)
790 EnsureConvertBuffer(samples);
791 buffer = Convert(samples);
794 Endian_Swap16_buf((uint16_t *)buffer, (uint16_t *)buffer, frames * samples->pkt->config.channels);
797 ConvertInit(samples);
798 if (m_convertState == NEED_CONVERT)
799 buffer = Convert(samples);
800 else if (m_convertState == NEED_BYTESWAP)
801 Endian_Swap16_buf((uint16_t *)buffer, (uint16_t *)buffer, frames * samples->pkt->config.channels);
809 maxFrames = std::min(frames, m_sinkFormat.m_frames);
810 written = m_sink->AddPackets(buffer, maxFrames, true, true);
813 Sleep(500*m_sinkFormat.m_frames/m_sinkFormat.m_sampleRate);
818 CLog::Log(LOGERROR, "CActiveAESink::OutputSamples - failed");
819 m_stats->UpdateSinkDelay(0, frames);
825 else if (written > maxFrames)
828 CLog::Log(LOGERROR, "CActiveAESink::OutputSamples - sink returned error");
829 m_stats->UpdateSinkDelay(0, samples->pool ? maxFrames : 0);
833 buffer += written*m_sinkFormat.m_frameSize;
834 sinkDelay = m_sink->GetDelay();
835 m_stats->UpdateSinkDelay(sinkDelay, samples->pool ? written : 0);
837 return sinkDelay*1000;
840 void CActiveAESink::ConvertInit(CSampleBuffer* samples)
842 if (CActiveAEResample::GetAESampleFormat(samples->pkt->config.fmt, samples->pkt->config.bits_per_sample) != m_sinkFormat.m_dataFormat)
844 m_convertFn = CAEConvert::FrFloat(m_sinkFormat.m_dataFormat);
846 _aligned_free(m_convertBuffer);
847 m_convertBufferSampleSize = samples->pkt->max_nb_samples;
848 m_convertBuffer = (uint8_t*)_aligned_malloc(samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize, 16);
849 memset(m_convertBuffer, 0, samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize);
850 m_convertState = NEED_CONVERT;
852 else if (AE_IS_RAW(m_requestedFormat.m_dataFormat) && CAEUtil::S16NeedsByteSwap(AE_FMT_S16NE, m_sinkFormat.m_dataFormat))
854 m_convertState = NEED_BYTESWAP;
857 m_convertState = SKIP_CONVERT;
860 void CActiveAESink::EnsureConvertBuffer(CSampleBuffer* samples)
862 if (!m_convertBuffer)
865 if (samples->pkt->max_nb_samples <= m_convertBufferSampleSize)
868 _aligned_free(m_convertBuffer);
869 m_convertBufferSampleSize = samples->pkt->max_nb_samples;
870 m_convertBuffer = (uint8_t*)_aligned_malloc(samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize, 16);
871 memset(m_convertBuffer, 0, samples->pkt->max_nb_samples * m_sinkFormat.m_channelLayout.Count() * m_sinkFormat.m_frameSize);
874 uint8_t* CActiveAESink::Convert(CSampleBuffer* samples)
876 m_convertFn((float*)samples->pkt->data[0], samples->pkt->nb_samples * samples->pkt->config.channels, m_convertBuffer);
877 return m_convertBuffer;
880 #define PI 3.1415926536f
882 void CActiveAESink::GenerateNoise()
884 int nb_floats = m_sinkFormat.m_frames*m_sinkFormat.m_channelLayout.Count();
885 float *noise = (float*)_aligned_malloc(nb_floats*sizeof(float), 16);
888 for(int i=0; i<nb_floats;i++)
892 R1 = (float) rand() / (float) RAND_MAX;
893 R2 = (float) rand() / (float) RAND_MAX;
897 noise[i] = (float) sqrt( -2.0f * log( R1 )) * cos( 2.0f * PI * R2 ) * 0.00001f;
900 AEDataFormat fmt = CActiveAEResample::GetAESampleFormat(m_sampleOfSilence.pkt->config.fmt, m_sampleOfSilence.pkt->config.bits_per_sample);
901 CAEConvert::AEConvertFrFn convertFn = CAEConvert::FrFloat(fmt);
902 convertFn(noise, nb_floats, m_sampleOfSilence.pkt->data[0]);
903 _aligned_free(noise);