Fixes for Mac/iOS

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
monroegm-disable-blank-issue-2
Esteban Papp 4 years ago
parent a75994e0b9
commit 07ea4edbc2

@ -179,7 +179,6 @@ void CLogFile::FormatLineV(const char * format, va_list argList)
void CLogFile::AboutSystem() void CLogFile::AboutSystem()
{ {
char szBuffer[MAX_LOGBUFFER_SIZE];
#if defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX) #if defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX)
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Write the system informations to the log // Write the system informations to the log
@ -190,6 +189,7 @@ void CLogFile::AboutSystem()
#endif // defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX) #endif // defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX)
#if defined(AZ_PLATFORM_WINDOWS) #if defined(AZ_PLATFORM_WINDOWS)
char szBuffer[MAX_LOGBUFFER_SIZE];
wchar_t szLanguageBufferW[64]; wchar_t szLanguageBufferW[64];
DEVMODE DisplayConfig; DEVMODE DisplayConfig;
OSVERSIONINFO OSVerInfo; OSVERSIONINFO OSVerInfo;

@ -66,8 +66,8 @@ int main(int argc, char* argv[])
processLaunchInfo.m_environmentVariables = &envVars; processLaunchInfo.m_environmentVariables = &envVars;
processLaunchInfo.m_showWindow = true; processLaunchInfo.m_showWindow = true;
AzFramework::ProcessWatcher* processWatcher = AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE); AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE);
application.Destroy(); application.Destroy();
return 0; return 0;

@ -205,8 +205,6 @@ namespace AzFramework
bool ProcessLauncher::LaunchProcess(const ProcessLaunchInfo& processLaunchInfo, ProcessData& processData) bool ProcessLauncher::LaunchProcess(const ProcessLaunchInfo& processLaunchInfo, ProcessData& processData)
{ {
bool result = false;
// note that the convention here is that it uses windows-shell style escaping of combined args with spaces in it // note that the convention here is that it uses windows-shell style escaping of combined args with spaces in it
// (so surrounding with quotes like param="hello world") // (so surrounding with quotes like param="hello world")
// this is so that the callers (which could be numerous) do not have to worry about this and sprinkle ifdefs // this is so that the callers (which could be numerous) do not have to worry about this and sprinkle ifdefs

@ -66,8 +66,8 @@ int main(int argc, char* argv[])
processLaunchInfo.m_environmentVariables = &envVars; processLaunchInfo.m_environmentVariables = &envVars;
processLaunchInfo.m_showWindow = true; processLaunchInfo.m_showWindow = true;
AzFramework::ProcessWatcher* processWatcher = AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE); AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE);
application.Destroy(); application.Destroy();
return 0; return 0;

@ -67,7 +67,6 @@ namespace UnitTest
AZStd::vector<Allocation> retiredAllocationsCurrent; AZStd::vector<Allocation> retiredAllocationsCurrent;
AZStd::vector<Allocation> retiredAllocationsPrevious; AZStd::vector<Allocation> retiredAllocationsPrevious;
const size_t AllocationCount = 100;
const size_t AllocationSizeRange = descriptor.m_allocationSizeMax - descriptor.m_allocationSizeMin; const size_t AllocationSizeRange = descriptor.m_allocationSizeMax - descriptor.m_allocationSizeMin;
AZStd::string outputString; AZStd::string outputString;

@ -56,8 +56,7 @@ namespace UnitTest
const uint32_t BufferConstantCount = 2; const uint32_t BufferConstantCount = 2;
const uint32_t BufferReadCount = 2; const uint32_t BufferReadCount = 2;
const uint32_t BufferReadWriteCount = 2; const uint32_t BufferReadWriteCount = 2;
const uint32_t BindingIndex = 1;
AZStd::unique_ptr<Factory> m_factory; AZStd::unique_ptr<Factory> m_factory;
AZStd::unique_ptr<SerializeContext> m_serializeContext; AZStd::unique_ptr<SerializeContext> m_serializeContext;

@ -252,9 +252,7 @@ namespace AZ
// Output file // Output file
AZStd::string shaderMSLOutputFile = RHI::BuildFileNameWithExtension(shaderSourceFile, tempFolder, "metal"); AZStd::string shaderMSLOutputFile = RHI::BuildFileNameWithExtension(shaderSourceFile, tempFolder, "metal");
bool outputFileWriteResult = false;
// Stage profile name parameter // Stage profile name parameter
const AZStd::string shaderModelVersion = "6_2"; const AZStd::string shaderModelVersion = "6_2";

@ -105,7 +105,6 @@ namespace AZ
} }
Fence* fenceToSignal = nullptr; Fence* fenceToSignal = nullptr;
uint64_t fenceToSignalValue = 0;
size_t byteCount = uploadRequest.m_byteCount; size_t byteCount = uploadRequest.m_byteCount;
size_t byteOffset = destMemoryView.GetOffset() + uploadRequest.m_byteOffset; size_t byteOffset = destMemoryView.GetOffset() + uploadRequest.m_byteOffset;
uint64_t queueValue = m_uploadFence.Increment(); uint64_t queueValue = m_uploadFence.Increment();
@ -183,8 +182,6 @@ namespace AZ
{ {
CommandQueue* commandQueue = static_cast<CommandQueue*>(queue); CommandQueue* commandQueue = static_cast<CommandQueue*>(queue);
FramePacket* framePacket = BeginFramePacket(commandQueue); FramePacket* framePacket = BeginFramePacket(commandQueue);
const uint16_t arraySize = image->GetDescriptor().m_arraySize;
const uint16_t imageMipLevels = image->GetDescriptor().m_mipLevels;
//[GFX TODO][ATOM-5605] - Cache alignments for all formats at Init //[GFX TODO][ATOM-5605] - Cache alignments for all formats at Init
const static uint32_t bufferOffsetAlign = [mtlDevice minimumTextureBufferAlignmentForPixelFormat: ConvertPixelFormat(image->GetDescriptor().m_format)]; const static uint32_t bufferOffsetAlign = [mtlDevice minimumTextureBufferAlignmentForPixelFormat: ConvertPixelFormat(image->GetDescriptor().m_format)];
@ -212,7 +209,6 @@ namespace AZ
if (subresourceLayout.m_size.m_height < subresourceLayout.m_rowCount) if (subresourceLayout.m_size.m_height < subresourceLayout.m_rowCount)
{ {
AZ_Error("Metal", false, "AsyncUploadQueue::QueueUpload expects ImageHeight '%d' to be bigger than or equal to the image's RowCount '%d'.", subresourceLayout.m_size.m_height, subresourceLayout.m_rowCount); AZ_Error("Metal", false, "AsyncUploadQueue::QueueUpload expects ImageHeight '%d' to be bigger than or equal to the image's RowCount '%d'.", subresourceLayout.m_size.m_height, subresourceLayout.m_rowCount);
RHI::AsyncWorkHandle::Null;
} }
// The final staging size for each CopyTextureRegion command // The final staging size for each CopyTextureRegion command
@ -281,8 +277,6 @@ namespace AZ
{ {
const uint8_t* subresourceDataStart = reinterpret_cast<const uint8_t*>(subresourceData.m_data) + depth * subresourceSlicePitch; const uint8_t* subresourceDataStart = reinterpret_cast<const uint8_t*>(subresourceData.m_data) + depth * subresourceSlicePitch;
MTLTextureDescriptor* mtlTextureDesc = ConvertImageDescriptor(image->GetDescriptor());
uint32_t startRow = 0; uint32_t startRow = 0;
uint32_t destHeight = 0; uint32_t destHeight = 0;
while (startRow < subresourceLayout.m_rowCount) while (startRow < subresourceLayout.m_rowCount)
@ -468,7 +462,6 @@ namespace AZ
MTLBlitOption mtlBlitOption = GetBlitOption(destImage->GetDescriptor().m_format); MTLBlitOption mtlBlitOption = GetBlitOption(destImage->GetDescriptor().m_format);
id<MTLTexture> tempTex = destImage->GetMemoryView().GetGpuAddress<id<MTLTexture>>();
[blitEncoder copyFromBuffer:framePacket->m_stagingResource [blitEncoder copyFromBuffer:framePacket->m_stagingResource
sourceOffset:framePacket->m_dataOffset sourceOffset:framePacket->m_dataOffset
sourceBytesPerRow:stagingRowPitch sourceBytesPerRow:stagingRowPitch

@ -102,8 +102,7 @@ namespace AZ
void BufferPool::ShutdownResourceInternal(RHI::Resource& resourceBase) void BufferPool::ShutdownResourceInternal(RHI::Resource& resourceBase)
{ {
Buffer& buffer = static_cast<Buffer&>(resourceBase); Buffer& buffer = static_cast<Buffer&>(resourceBase);
auto& device = static_cast<Device&>(GetDevice());
if (auto* resolver = GetResolver()) if (auto* resolver = GetResolver())
{ {
resolver->OnResourceShutdown(resourceBase); resolver->OnResourceShutdown(resourceBase);

@ -72,7 +72,7 @@ namespace AZ
commandListPoolDescriptor.m_collectLatency = descriptor.m_frameCountMax; commandListPoolDescriptor.m_collectLatency = descriptor.m_frameCountMax;
commandListPool.Init(commandListPoolDescriptor); commandListPool.Init(commandListPoolDescriptor);
m_commandListSubAllocators[queueIdx].SetInitFunction([this, &commandListPool] m_commandListSubAllocators[queueIdx].SetInitFunction([&commandListPool]
(CommandListSubAllocator& subAllocator) (CommandListSubAllocator& subAllocator)
{ {
subAllocator.Init(commandListPool); subAllocator.Init(commandListPool);

@ -90,7 +90,7 @@ namespace AZ
void Collect(); void Collect();
private: private:
CommandListPool* m_commandListPool = nullptr; [[maybe_unused]] CommandListPool* m_commandListPool = nullptr;
AZStd::vector<CommandList*> m_activeLists; AZStd::vector<CommandList*> m_activeLists;
AZStd::array<CommandListPool, RHI::HardwareQueueClassCount> m_commandListPools; AZStd::array<CommandListPool, RHI::HardwareQueueClassCount> m_commandListPools;

@ -25,11 +25,9 @@ namespace AZ
RHI::ResultCode ImagePoolResolver::UpdateImage(const RHI::ImageUpdateRequest& request, size_t& bytesTransferred) RHI::ResultCode ImagePoolResolver::UpdateImage(const RHI::ImageUpdateRequest& request, size_t& bytesTransferred)
{ {
Image* image = static_cast<Image*>(request.m_image); Image* image = static_cast<Image*>(request.m_image);
auto& device = static_cast<Device&>(GetDevice());
const RHI::ImageSubresourceLayout& sourceSubresourceLayout = request.m_sourceSubresourceLayout; const RHI::ImageSubresourceLayout& sourceSubresourceLayout = request.m_sourceSubresourceLayout;
const RHI::Origin& imageSubresourcePixelOffset = request.m_imageSubresourcePixelOffset;
const uint32_t stagingRowPitch = sourceSubresourceLayout.m_bytesPerRow; const uint32_t stagingRowPitch = sourceSubresourceLayout.m_bytesPerRow;
const uint32_t stagingSlicePitch = sourceSubresourceLayout.m_bytesPerImage; const uint32_t stagingSlicePitch = sourceSubresourceLayout.m_bytesPerImage;
const uint32_t stagingSize = stagingSlicePitch * sourceSubresourceLayout.m_size.m_depth; const uint32_t stagingSize = stagingSlicePitch * sourceSubresourceLayout.m_size.m_depth;

@ -42,8 +42,6 @@ namespace AZ
void NullDescriptorManager::Shutdown() void NullDescriptorManager::Shutdown()
{ {
const Device& device = static_cast<Device&>(GetDevice());
m_nullImages.clear(); m_nullImages.clear();
m_nullBuffer.m_memoryView = {}; m_nullBuffer.m_memoryView = {};
m_nullMtlSamplerState = nil; m_nullMtlSamplerState = nil;
@ -94,7 +92,6 @@ namespace AZ
textureSizeAndAlign.size = memoryRequirements.m_sizeInBytes; textureSizeAndAlign.size = memoryRequirements.m_sizeInBytes;
const size_t alignedHeapSize = RHI::AlignUp(heapSize, textureSizeAndAlign.align); const size_t alignedHeapSize = RHI::AlignUp(heapSize, textureSizeAndAlign.align);
const uint32_t bytesPerPixel = RHI::GetFormatSize(m_nullImages[imageIndex].m_imageDescriptor.m_format);
if(imageIndex == static_cast<uint32_t>(NullDescriptorManager::ImageTypes::TextureBuffer)) if(imageIndex == static_cast<uint32_t>(NullDescriptorManager::ImageTypes::TextureBuffer))
{ {
m_nullImages[imageIndex].m_memoryView = device.CreateImagePlaced(m_nullImages[imageIndex].m_imageDescriptor, m_nullDescriptorHeap, alignedHeapSize, textureSizeAndAlign, MTLTextureTypeTextureBuffer); m_nullImages[imageIndex].m_memoryView = device.CreateImagePlaced(m_nullImages[imageIndex].m_imageDescriptor, m_nullDescriptorHeap, alignedHeapSize, textureSizeAndAlign, MTLTextureTypeTextureBuffer);

@ -26,10 +26,9 @@ namespace AZ
RHI::ResultCode QueryPool::InitInternal(RHI::Device& baseDevice, const RHI::QueryPoolDescriptor& descriptor) RHI::ResultCode QueryPool::InitInternal(RHI::Device& baseDevice, const RHI::QueryPoolDescriptor& descriptor)
{ {
auto& device = static_cast<Device&>(baseDevice); auto& device = static_cast<Device&>(baseDevice);
id<MTLDevice> mtlDevice = device.GetMtlDevice();
NSError* error = nil;
#if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING
id<MTLDevice> mtlDevice = device.GetMtlDevice();
NSArray<id<MTLCounterSet>> * counterSets = [mtlDevice counterSets]; NSArray<id<MTLCounterSet>> * counterSets = [mtlDevice counterSets];
CacheCounterIndices(counterSets); CacheCounterIndices(counterSets);
#endif #endif
@ -47,6 +46,7 @@ namespace AZ
#if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING
case RHI::QueryType::Timestamp: case RHI::QueryType::Timestamp:
{ {
NSError* error = nil;
NSUInteger timeStampCounterIndex = [counterSets indexOfObjectPassingTest:^BOOL(id<MTLCounterSet> mtlCounterSet, NSUInteger idx, BOOL *stop) NSUInteger timeStampCounterIndex = [counterSets indexOfObjectPassingTest:^BOOL(id<MTLCounterSet> mtlCounterSet, NSUInteger idx, BOOL *stop)
{ {
if ([mtlCounterSet.name isEqualToString:MTLCommonCounterSetTimestamp]) if ([mtlCounterSet.name isEqualToString:MTLCommonCounterSetTimestamp])
@ -77,6 +77,7 @@ namespace AZ
} }
case RHI::QueryType::PipelineStatistics: case RHI::QueryType::PipelineStatistics:
{ {
NSError* error = nil;
NSUInteger statisticCounterIndex = [counterSets indexOfObjectPassingTest:^BOOL(id<MTLCounterSet> mtlCounterSet, NSUInteger idx, BOOL *stop) NSUInteger statisticCounterIndex = [counterSets indexOfObjectPassingTest:^BOOL(id<MTLCounterSet> mtlCounterSet, NSUInteger idx, BOOL *stop)
{ {
if ([mtlCounterSet.name isEqualToString:MTLCommonCounterSetStatistic]) if ([mtlCounterSet.name isEqualToString:MTLCommonCounterSetStatistic])
@ -127,9 +128,6 @@ namespace AZ
RHI::ResultCode QueryPool::GetResultsInternal(uint32_t startIndex, uint32_t queryCount, uint64_t* results, uint32_t resultsCount, RHI::QueryResultFlagBits flags) RHI::ResultCode QueryPool::GetResultsInternal(uint32_t startIndex, uint32_t queryCount, uint64_t* results, uint32_t resultsCount, RHI::QueryResultFlagBits flags)
{ {
auto& device = static_cast<Device&>(GetDevice());
MTLCommandBufferStatus commandBufferStatus = MTLCommandBufferStatusError;
switch(GetDescriptor().m_type) switch(GetDescriptor().m_type)
{ {
case RHI::QueryType::Occlusion: case RHI::QueryType::Occlusion:

@ -115,12 +115,10 @@ namespace AZ
const RHI::ImageScopeAttachmentDescriptor& bindingDescriptor = scopeAttachment->GetDescriptor(); const RHI::ImageScopeAttachmentDescriptor& bindingDescriptor = scopeAttachment->GetDescriptor();
id<MTLTexture> imageViewMtlTexture = imageView->GetMemoryView().GetGpuAddress<id<MTLTexture>>(); id<MTLTexture> imageViewMtlTexture = imageView->GetMemoryView().GetGpuAddress<id<MTLTexture>>();
const bool isFullView = imageView->IsFullView();
const bool isClearAction = bindingDescriptor.m_loadStoreAction.m_loadAction == RHI::AttachmentLoadAction::Clear; const bool isClearAction = bindingDescriptor.m_loadStoreAction.m_loadAction == RHI::AttachmentLoadAction::Clear;
const bool isClearActionStencil = bindingDescriptor.m_loadStoreAction.m_loadActionStencil == RHI::AttachmentLoadAction::Clear; const bool isClearActionStencil = bindingDescriptor.m_loadStoreAction.m_loadActionStencil == RHI::AttachmentLoadAction::Clear;
const bool isLoadAction = bindingDescriptor.m_loadStoreAction.m_loadAction == RHI::AttachmentLoadAction::Load; const bool isLoadAction = bindingDescriptor.m_loadStoreAction.m_loadAction == RHI::AttachmentLoadAction::Load;
const bool isLoadActionStencil = bindingDescriptor.m_loadStoreAction.m_loadActionStencil == RHI::AttachmentLoadAction::Load;
const bool isStoreAction = bindingDescriptor.m_loadStoreAction.m_storeAction == RHI::AttachmentStoreAction::Store; const bool isStoreAction = bindingDescriptor.m_loadStoreAction.m_storeAction == RHI::AttachmentStoreAction::Store;
const bool isStoreActionStencil = bindingDescriptor.m_loadStoreAction.m_storeActionStencil == RHI::AttachmentStoreAction::Store; const bool isStoreActionStencil = bindingDescriptor.m_loadStoreAction.m_storeActionStencil == RHI::AttachmentStoreAction::Store;
@ -158,7 +156,6 @@ namespace AZ
{ {
mtlStoreActionStencil = MTLStoreActionStore; mtlStoreActionStencil = MTLStoreActionStore;
} }
const RHI::ImageViewDescriptor& imgViewDescriptor = imageView->GetDescriptor();
const AZStd::vector<RHI::ScopeAttachmentUsageAndAccess>& usagesAndAccesses = scopeAttachment->GetUsageAndAccess(); const AZStd::vector<RHI::ScopeAttachmentUsageAndAccess>& usagesAndAccesses = scopeAttachment->GetUsageAndAccess();
for (const RHI::ScopeAttachmentUsageAndAccess& usageAndAccess : usagesAndAccesses) for (const RHI::ScopeAttachmentUsageAndAccess& usageAndAccess : usagesAndAccesses)
{ {

@ -26,7 +26,6 @@ namespace AZ
{ {
Device& device = static_cast<Device&>(deviceBase); Device& device = static_cast<Device&>(deviceBase);
m_device = &device; m_device = &device;
const RHI::ShaderResourceGroupLayout& layout = *descriptor.m_layout;
m_srgLayout = descriptor.m_layout; m_srgLayout = descriptor.m_layout;
return RHI::ResultCode::Success; return RHI::ResultCode::Success;
} }

@ -50,7 +50,6 @@ namespace AZ
RHI::ResultCode StreamingImagePool::InitImageInternal(const RHI::StreamingImageInitRequest& request) RHI::ResultCode StreamingImagePool::InitImageInternal(const RHI::StreamingImageInitRequest& request)
{ {
Image& image = static_cast<Image&>(*request.m_image); Image& image = static_cast<Image&>(*request.m_image);
auto& device = static_cast<Device&>(GetDevice());
MemoryView memoryView = GetDevice().CreateImageCommitted(image.GetDescriptor()); MemoryView memoryView = GetDevice().CreateImageCommitted(image.GetDescriptor());
if (!memoryView.IsValid()) if (!memoryView.IsValid())

@ -123,9 +123,6 @@ namespace AZ
RHI::ResultCode SwapChain::InitImageInternal(const InitImageRequest& request) RHI::ResultCode SwapChain::InitImageInternal(const InitImageRequest& request)
{ {
const RHI::SwapChainDescriptor& descriptor = GetDescriptor();
Device& device = GetDevice();
Name name(AZStd::string::format("SwapChainImage_%d", request.m_imageIndex)); Name name(AZStd::string::format("SwapChainImage_%d", request.m_imageIndex));
Image& image = static_cast<Image&>(*request.m_image); Image& image = static_cast<Image&>(*request.m_image);

@ -241,13 +241,14 @@ public:
AZStd::size_t GetData(void** outputData, AZStd::size_t numFrames, const SAudioInputConfig& targetConfig, bool shouldDeinterleave) override AZStd::size_t GetData(void** outputData, AZStd::size_t numFrames, const SAudioInputConfig& targetConfig, bool shouldDeinterleave) override
{ {
bool changeSampleType = (targetConfig.m_sampleType != m_config.m_sampleType);
bool changeSampleRate = (targetConfig.m_sampleRate != m_config.m_sampleRate);
bool changeNumChannels = (targetConfig.m_numChannels != m_config.m_numChannels);
#if defined(USE_LIBSAMPLERATE) #if defined(USE_LIBSAMPLERATE)
// pending port of LIBSAMPLERATE to MacOS // pending port of LIBSAMPLERATE to MacOS
return {}; return {};
#else #else
bool changeSampleType = (targetConfig.m_sampleType != m_config.m_sampleType);
bool changeSampleRate = (targetConfig.m_sampleRate != m_config.m_sampleRate);
bool changeNumChannels = (targetConfig.m_numChannels != m_config.m_numChannels);
if (changeSampleType || changeNumChannels) if (changeSampleType || changeNumChannels)
{ {
// Without the SRC library, any change is unsupported! // Without the SRC library, any change is unsupported!

@ -187,13 +187,14 @@ public:
AZStd::size_t GetData(void** outputData, AZStd::size_t numFrames, const SAudioInputConfig& targetConfig, bool shouldDeinterleave) override AZStd::size_t GetData(void** outputData, AZStd::size_t numFrames, const SAudioInputConfig& targetConfig, bool shouldDeinterleave) override
{ {
bool changeSampleType = (targetConfig.m_sampleType != m_config.m_sampleType);
bool changeSampleRate = (targetConfig.m_sampleRate != m_config.m_sampleRate);
bool changeNumChannels = (targetConfig.m_numChannels != m_config.m_numChannels);
#if defined(USE_LIBSAMPLERATE) #if defined(USE_LIBSAMPLERATE)
// pending port of LIBSAMPLERATE to iOS // pending port of LIBSAMPLERATE to iOS
return {}; return {};
#else #else
bool changeSampleType = (targetConfig.m_sampleType != m_config.m_sampleType);
bool changeSampleRate = (targetConfig.m_sampleRate != m_config.m_sampleRate);
bool changeNumChannels = (targetConfig.m_numChannels != m_config.m_numChannels);
if (changeSampleType || changeNumChannels) if (changeSampleType || changeNumChannels)
{ {
// Without the SRC library, any change is unsupported! // Without the SRC library, any change is unsupported!

Loading…
Cancel
Save