~aleteoryx/muditaos

ref: b890bcd6e32223e624d0d63af50bcd2219469d32 muditaos/module-audio/Audio/StreamFactory.cpp -rw-r--r-- 1.7 KiB
b890bcd6 — Marcin Smoczyński [EGD-5260] Add A2DP playback to audio 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// 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 <math/Math.hpp>

#include <algorithm>
#include <memory>
#include <vector>

#include <cassert>

using namespace audio;

StreamFactory::StreamFactory(Endpoint::Capabilities factoryCaps, unsigned int bufferingSize)
    : caps(std::move(factoryCaps)), bufferingSize(bufferingSize)
{}

auto StreamFactory::makeStream(const Source &source, const Sink &sink) -> std::unique_ptr<Stream>
{
    auto negotiatedCaps = negotiateCaps({source, sink});

    return std::make_unique<Stream>(getAllocator(negotiatedCaps.usesDMA), negotiatedCaps.maxBlockSize, bufferingSize);
}

auto StreamFactory::negotiateCaps(std::vector<std::reference_wrapper<const Endpoint>> 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;
    }
}