// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "StreamFactory.hpp" #include "Endpoint.hpp" #include #include #include #include #include using namespace audio; StreamFactory::StreamFactory(Endpoint::Capabilities factoryCaps) : caps(std::move(factoryCaps)) {} auto StreamFactory::makeStream(const Source &source, const Sink &sink) -> std::unique_ptr { auto negotiatedCaps = negotiateCaps({source, sink}); return std::make_unique(getAllocator(negotiatedCaps.usesDMA), negotiatedCaps.maxBlockSize); } auto StreamFactory::negotiateCaps(std::vector> v) -> Endpoint::Capabilities { auto negotiatedCaps = caps; for (const auto &endpointRef : v) { auto &endpointCaps = endpointRef.get().getCapabilities(); negotiatedCaps.maxBlockSize = std::min(negotiatedCaps.maxBlockSize, endpointCaps.maxBlockSize); negotiatedCaps.minBlockSize = std::max(negotiatedCaps.minBlockSize, endpointCaps.minBlockSize); negotiatedCaps.usesDMA = negotiatedCaps.usesDMA || endpointCaps.usesDMA; } negotiatedCaps.minBlockSize = binary::ceilPowerOfTwo(negotiatedCaps.minBlockSize); negotiatedCaps.maxBlockSize = binary::floorPowerOfTwo(negotiatedCaps.maxBlockSize); assert(negotiatedCaps.minBlockSize <= negotiatedCaps.maxBlockSize); return negotiatedCaps; } auto StreamFactory::getAllocator(bool usesDMA) -> Stream::Allocator & { if (usesDMA) { return nonCacheableAlloc; } else { return stdAlloc; } }