Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85abc314 authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Android (Google) Code Review
Browse files

Merge changes from topic "primary-aidl-hal" into udc-qpr-dev

* changes:
  audio: Ensure proper priority and scheduler for service threads
  audio: Implement the major functionality of the primary CF HAL
  audio: Make renamings suggested by reviewers
parents dcc65006 ad50acdd
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -106,6 +106,9 @@ void ThreadController::workerThread() {
        std::lock_guard<std::mutex> lock(mWorkerLock);
        mWorkerState = error.empty() ? WorkerState::RUNNING : WorkerState::STOPPED;
        mError = error;
#if defined(__ANDROID__)
        mTid = pthread_gettid_np(pthread_self());
#endif
    }
    mWorkerCv.notify_one();
    if (!error.empty()) return;
+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

#pragma once

#include <sys/types.h>

#include <atomic>
#include <condition_variable>
#include <mutex>
@@ -52,6 +54,10 @@ class ThreadController {
        std::lock_guard<std::mutex> lock(mWorkerLock);
        return mError;
    }
    pid_t getTid() {
        std::lock_guard<std::mutex> lock(mWorkerLock);
        return mTid;
    }
    void stop();
    // Direct use of 'join' assumes that the StreamLogic is not intended
    // to run forever, and is guaranteed to exit by itself. This normally
@@ -78,6 +84,7 @@ class ThreadController {
    std::condition_variable mWorkerCv;
    WorkerState mWorkerState GUARDED_BY(mWorkerLock) = WorkerState::INITIAL;
    std::string mError GUARDED_BY(mWorkerLock);
    pid_t mTid GUARDED_BY(mWorkerLock) = -1;
    // The atomic lock-free variable is used to prevent priority inversions
    // that can occur when a high priority worker tries to acquire the lock
    // which has been taken by a lower priority control thread which in its turn
@@ -143,6 +150,7 @@ class StreamWorker : public LogicImpl {
    void resume() { mThread.resume(); }
    bool hasError() { return mThread.hasError(); }
    std::string getError() { return mThread.getError(); }
    pid_t getTid() { return mThread.getTid(); }
    void stop() { mThread.stop(); }
    void join() { mThread.join(); }
    bool waitForAtLeastOneCycle() { return mThread.waitForAtLeastOneCycle(); }
+8 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ class StreamWorkerInvalidTest : public testing::TestWithParam<bool> {
TEST_P(StreamWorkerInvalidTest, Uninitialized) {
    EXPECT_FALSE(worker.hasWorkerCycleCalled());
    EXPECT_FALSE(worker.hasError());
    EXPECT_LE(worker.getTid(), 0);
}

TEST_P(StreamWorkerInvalidTest, UninitializedPauseIgnored) {
@@ -105,6 +106,9 @@ TEST_P(StreamWorkerInvalidTest, Start) {
    EXPECT_FALSE(worker.start());
    EXPECT_FALSE(worker.hasWorkerCycleCalled());
    EXPECT_TRUE(worker.hasError());
#if defined(__ANDROID__)
    EXPECT_GT(worker.getTid(), 0);
#endif
}

TEST_P(StreamWorkerInvalidTest, PauseIgnored) {
@@ -136,12 +140,16 @@ static constexpr unsigned kWorkerIdleCheckTime = 50 * 1000;
TEST_P(StreamWorkerTest, Uninitialized) {
    EXPECT_FALSE(worker.hasWorkerCycleCalled());
    EXPECT_FALSE(worker.hasError());
    EXPECT_LE(worker.getTid(), 0);
}

TEST_P(StreamWorkerTest, Start) {
    ASSERT_TRUE(worker.start());
    EXPECT_TRUE(worker.waitForAtLeastOneCycle());
    EXPECT_FALSE(worker.hasError());
#if defined(__ANDROID__)
    EXPECT_GT(worker.getTid(), 0);
#endif
}

TEST_P(StreamWorkerTest, StartStop) {
+2 −0
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ cc_library {
        "bluetooth/DevicePortProxy.cpp",
        "bluetooth/ModuleBluetooth.cpp",
        "bluetooth/StreamBluetooth.cpp",
        "primary/PrimaryMixer.cpp",
        "primary/StreamPrimary.cpp",
        "r_submix/ModuleRemoteSubmix.cpp",
        "r_submix/RemoteSubmixUtils.cpp",
        "r_submix/SubmixRoute.cpp",
+74 −84
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ static AudioRoute createRoute(const std::vector<AudioPort>& sources, const Audio
// Device ports:
//  * "Speaker", OUT_SPEAKER, default
//    - no profiles specified
//  * "Built-in Mic", IN_MICROPHONE, default
//  * "Built-In Mic", IN_MICROPHONE, default
//    - no profiles specified
//  * "Telephony Tx", OUT_TELEPHONY_TX
//    - no profiles specified
@@ -148,45 +148,34 @@ static AudioRoute createRoute(const std::vector<AudioPort>& sources, const Audio
// Mix ports:
//  * "primary output", PRIMARY, 1 max open, 1 max active stream
//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//  * "compressed offload", DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING, 1 max open, 1 max active stream
//    - profile MP3; MONO, STEREO; 44100, 48000
//  * "primary input", 2 max open, 2 max active streams
//    - profile PCM 16-bit; MONO, STEREO, FRONT_BACK;
//        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
//    - profile PCM 24-bit; MONO, STEREO, FRONT_BACK;
//        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
//  * "primary input", 1 max open, 1 max active stream
//    - profile PCM 16-bit; MONO, STEREO;
//        8000, 11025, 16000, 32000, 44100, 48000
//  * "telephony_tx", 1 max open, 1 max active stream
//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//  * "telephony_rx", 1 max open, 1 max active stream
//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//  * "fm_tuner", 1 max open, 1 max active stream
//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//
// Routes:
//  "primary out", "compressed offload" -> "Speaker"
//  "Built-in Mic" -> "primary input"
//  "telephony_tx" -> "Telephony Tx"
//  "primary out" -> "Speaker"
//  "Built-In Mic" -> "primary input"
//  "Telephony Rx" -> "telephony_rx"
//  "telephony_tx" -> "Telephony Tx"
//  "FM Tuner" -> "fm_tuner"
//
// Initial port configs:
//  * "Speaker" device port: PCM 24-bit; STEREO; 48000
//  * "Built-in Mic" device port: PCM 24-bit; MONO; 48000
//  * "Telephony Tx" device port: PCM 24-bit; MONO; 48000
//  * "Telephony Rx" device port: PCM 24-bit; MONO; 48000
//  * "FM Tuner" device port: PCM 24-bit; STEREO; 48000
//  * "Speaker" device port: PCM 16-bit; STEREO; 48000
//  * "Built-In Mic" device port: PCM 16-bit; MONO; 48000
//  * "Telephony Tx" device port: PCM 16-bit; MONO; 48000
//  * "Telephony Rx" device port: PCM 16-bit; MONO; 48000
//  * "FM Tuner" device port: PCM 16-bit; STEREO; 48000
//
std::unique_ptr<Configuration> getPrimaryConfiguration() {
    static const Configuration configuration = []() {
        const std::vector<AudioProfile> standardPcmAudioProfiles = {
                createProfile(PcmType::INT_16_BIT,
                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
                              {8000, 11025, 16000, 32000, 44100, 48000}),
                createProfile(PcmType::INT_24_BIT,
                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
                              {8000, 11025, 16000, 32000, 44100, 48000})};
        Configuration c;
@@ -199,17 +188,17 @@ std::unique_ptr<Configuration> getPrimaryConfiguration() {
                                           1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
        c.ports.push_back(speakerOutDevice);
        c.initialConfigs.push_back(
                createPortConfig(speakerOutDevice.id, speakerOutDevice.id, PcmType::INT_24_BIT,
                createPortConfig(speakerOutDevice.id, speakerOutDevice.id, PcmType::INT_16_BIT,
                                 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false,
                                 createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)));

        AudioPort micInDevice =
                createPort(c.nextPortId++, "Built-in Mic", 0, true,
                createPort(c.nextPortId++, "Built-In Mic", 0, true,
                           createDeviceExt(AudioDeviceType::IN_MICROPHONE,
                                           1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
        c.ports.push_back(micInDevice);
        c.initialConfigs.push_back(
                createPortConfig(micInDevice.id, micInDevice.id, PcmType::INT_24_BIT,
                createPortConfig(micInDevice.id, micInDevice.id, PcmType::INT_16_BIT,
                                 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
                                 createDeviceExt(AudioDeviceType::IN_MICROPHONE, 0)));

@@ -219,7 +208,7 @@ std::unique_ptr<Configuration> getPrimaryConfiguration() {
        c.ports.push_back(telephonyTxOutDevice);
        c.initialConfigs.push_back(
                createPortConfig(telephonyTxOutDevice.id, telephonyTxOutDevice.id,
                                 PcmType::INT_24_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
                                 PcmType::INT_16_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
                                 false, createDeviceExt(AudioDeviceType::OUT_TELEPHONY_TX, 0)));

        AudioPort telephonyRxInDevice =
@@ -228,14 +217,14 @@ std::unique_ptr<Configuration> getPrimaryConfiguration() {
        c.ports.push_back(telephonyRxInDevice);
        c.initialConfigs.push_back(
                createPortConfig(telephonyRxInDevice.id, telephonyRxInDevice.id,
                                 PcmType::INT_24_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
                                 PcmType::INT_16_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
                                 true, createDeviceExt(AudioDeviceType::IN_TELEPHONY_RX, 0)));

        AudioPort fmTunerInDevice = createPort(c.nextPortId++, "FM Tuner", 0, true,
                                               createDeviceExt(AudioDeviceType::IN_FM_TUNER, 0));
        c.ports.push_back(fmTunerInDevice);
        c.initialConfigs.push_back(
                createPortConfig(fmTunerInDevice.id, fmTunerInDevice.id, PcmType::INT_24_BIT,
                createPortConfig(fmTunerInDevice.id, fmTunerInDevice.id, PcmType::INT_16_BIT,
                                 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, true,
                                 createDeviceExt(AudioDeviceType::IN_FM_TUNER, 0)));

@@ -249,30 +238,12 @@ std::unique_ptr<Configuration> getPrimaryConfiguration() {
                                      standardPcmAudioProfiles.end());
        c.ports.push_back(primaryOutMix);

        AudioPort compressedOffloadOutMix =
                createPort(c.nextPortId++, "compressed offload",
                           makeBitPositionFlagMask({AudioOutputFlags::DIRECT,
                                                    AudioOutputFlags::COMPRESS_OFFLOAD,
                                                    AudioOutputFlags::NON_BLOCKING}),
                           false, createPortMixExt(1, 1));
        compressedOffloadOutMix.profiles.push_back(
                createProfile(::android::MEDIA_MIMETYPE_AUDIO_MPEG,
                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
                              {44100, 48000}));
        c.ports.push_back(compressedOffloadOutMix);

        AudioPort primaryInMix =
                createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(2, 2));
                createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(1, 1));
        primaryInMix.profiles.push_back(
                createProfile(PcmType::INT_16_BIT,
                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
                               AudioChannelLayout::LAYOUT_FRONT_BACK},
                              {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
        primaryInMix.profiles.push_back(
                createProfile(PcmType::INT_24_BIT,
                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
                               AudioChannelLayout::LAYOUT_FRONT_BACK},
                              {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
                              {8000, 11025, 16000, 32000, 44100, 48000}));
        c.ports.push_back(primaryInMix);

        AudioPort telephonyTxOutMix =
@@ -296,10 +267,10 @@ std::unique_ptr<Configuration> getPrimaryConfiguration() {
                                     standardPcmAudioProfiles.end());
        c.ports.push_back(fmTunerInMix);

        c.routes.push_back(createRoute({primaryOutMix, compressedOffloadOutMix}, speakerOutDevice));
        c.routes.push_back(createRoute({primaryOutMix}, speakerOutDevice));
        c.routes.push_back(createRoute({micInDevice}, primaryInMix));
        c.routes.push_back(createRoute({telephonyTxOutMix}, telephonyTxOutDevice));
        c.routes.push_back(createRoute({telephonyRxInDevice}, telephonyRxInMix));
        c.routes.push_back(createRoute({telephonyTxOutMix}, telephonyTxOutDevice));
        c.routes.push_back(createRoute({fmTunerInDevice}, fmTunerInMix));

        c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());
@@ -320,15 +291,15 @@ std::unique_ptr<Configuration> getPrimaryConfiguration() {
//
// Device ports:
//  * "Remote Submix Out", OUT_SUBMIX
//    - profile PCM 24-bit; STEREO; 48000
//    - profile PCM 16-bit; STEREO; 48000
//  * "Remote Submix In", IN_SUBMIX
//    - profile PCM 24-bit; STEREO; 48000
//    - profile PCM 16-bit; STEREO; 48000
//
// Mix ports:
//  * "r_submix output", stream count unlimited
//    - profile PCM 24-bit; STEREO; 48000
//  * "r_submix input", stream count unlimited
//    - profile PCM 24-bit; STEREO; 48000
//  * "r_submix output", 1 max open, 1 max active stream
//    - profile PCM 16-bit; STEREO; 48000
//  * "r_submix input", 1 max open, 1 max active stream
//    - profile PCM 16-bit; STEREO; 48000
//
// Routes:
//  "r_submix output" -> "Remote Submix Out"
@@ -345,27 +316,27 @@ std::unique_ptr<Configuration> getRSubmixConfiguration() {
                           createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0,
                                           AudioDeviceDescription::CONNECTION_VIRTUAL));
        rsubmixOutDevice.profiles.push_back(
                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
                createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
        c.ports.push_back(rsubmixOutDevice);

        AudioPort rsubmixInDevice = createPort(c.nextPortId++, "Remote Submix In", 0, true,
                                               createDeviceExt(AudioDeviceType::IN_SUBMIX, 0));
        rsubmixInDevice.profiles.push_back(
                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
                createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
        c.ports.push_back(rsubmixInDevice);

        // Mix ports

        AudioPort rsubmixOutMix =
                createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(0, 0));
                createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(1, 1));
        rsubmixOutMix.profiles.push_back(
                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
                createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
        c.ports.push_back(rsubmixOutMix);

        AudioPort rsubmixInMix =
                createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(0, 0));
                createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(1, 1));
        rsubmixInMix.profiles.push_back(
                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
                createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
        c.ports.push_back(rsubmixInMix);

        c.routes.push_back(createRoute({rsubmixOutMix}, rsubmixOutDevice));
@@ -479,14 +450,17 @@ std::unique_ptr<Configuration> getUsbConfiguration() {
// Mix ports:
//  * "test output", 1 max open, 1 max active stream
//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//  * "compressed offload", DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING, 1 max open, 1 max active stream
//  * "test fast output", 1 max open, 1 max active stream
//    - profile PCM 24-bit; STEREO; 44100, 48000
//  * "test compressed offload", DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING, 1 max open, 1 max active
//  stream
//    - profile MP3; MONO, STEREO; 44100, 48000
//  * "test input", 2 max open, 2 max active streams
//    - profile PCM 24-bit; MONO, STEREO, FRONT_BACK;
//        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
//        8000, 11025, 16000, 22050, 32000, 44100, 48000
//
// Routes:
//  "test output", "compressed offload" -> "Test Out"
//  "test output", "test fast output", "test compressed offload" -> "Test Out"
//  "Test In" -> "test input"
//
// Initial port configs:
@@ -525,8 +499,15 @@ std::unique_ptr<Configuration> getStubConfiguration() {
                              {8000, 11025, 16000, 32000, 44100, 48000}));
        c.ports.push_back(testOutMix);

        AudioPort testFastOutMix = createPort(c.nextPortId++, "test fast output",
                                              makeBitPositionFlagMask({AudioOutputFlags::FAST}),
                                              false, createPortMixExt(1, 1));
        testFastOutMix.profiles.push_back(createProfile(
                PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {44100, 48000}));
        c.ports.push_back(testFastOutMix);

        AudioPort compressedOffloadOutMix =
                createPort(c.nextPortId++, "compressed offload",
                createPort(c.nextPortId++, "test compressed offload",
                           makeBitPositionFlagMask({AudioOutputFlags::DIRECT,
                                                    AudioOutputFlags::COMPRESS_OFFLOAD,
                                                    AudioOutputFlags::NON_BLOCKING}),
@@ -543,15 +524,16 @@ std::unique_ptr<Configuration> getStubConfiguration() {
                createProfile(PcmType::INT_16_BIT,
                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
                               AudioChannelLayout::LAYOUT_FRONT_BACK},
                              {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
                              {8000, 11025, 16000, 22050, 32000, 44100, 48000}));
        testInMIx.profiles.push_back(
                createProfile(PcmType::INT_24_BIT,
                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
                               AudioChannelLayout::LAYOUT_FRONT_BACK},
                              {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
                              {8000, 11025, 16000, 22050, 32000, 44100, 48000}));
        c.ports.push_back(testInMIx);

        c.routes.push_back(createRoute({testOutMix, compressedOffloadOutMix}, testOutDevice));
        c.routes.push_back(
                createRoute({testOutMix, testFastOutMix, compressedOffloadOutMix}, testOutDevice));
        c.routes.push_back(createRoute({testInDevice}, testInMIx));

        c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());
@@ -566,7 +548,7 @@ std::unique_ptr<Configuration> getStubConfiguration() {
// Device ports:
//  * "BT A2DP Out", OUT_DEVICE, CONNECTION_BT_A2DP
//    - profile PCM 16-bit; STEREO; 44100, 48000, 88200, 96000
//  * "BT A2DP Headphones", OUT_HEADSET, CONNECTION_BT_A2DP
//  * "BT A2DP Headphones", OUT_HEADPHONE, CONNECTION_BT_A2DP
//    - profile PCM 16-bit; STEREO; 44100, 48000, 88200, 96000
//  * "BT A2DP Speaker", OUT_SPEAKER, CONNECTION_BT_A2DP
//    - profile PCM 16-bit; STEREO; 44100, 48000, 88200, 96000
@@ -597,13 +579,18 @@ std::unique_ptr<Configuration> getBluetoothConfiguration() {
                createPort(c.nextPortId++, "BT A2DP Out", 0, false,
                           createDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
                                           AudioDeviceDescription::CONNECTION_BT_A2DP));
        btOutDevice.profiles.insert(btOutDevice.profiles.begin(), standardPcmAudioProfiles.begin(),
                                    standardPcmAudioProfiles.end());
        c.ports.push_back(btOutDevice);
        c.connectedProfiles[btOutDevice.id] = standardPcmAudioProfiles;

        AudioPort btOutHeadphone =
                createPort(c.nextPortId++, "BT A2DP Headphones", 0, false,
                           createDeviceExt(AudioDeviceType::OUT_HEADSET, 0,
                           createDeviceExt(AudioDeviceType::OUT_HEADPHONE, 0,
                                           AudioDeviceDescription::CONNECTION_BT_A2DP));
        btOutHeadphone.profiles.insert(btOutHeadphone.profiles.begin(),
                                       standardPcmAudioProfiles.begin(),
                                       standardPcmAudioProfiles.end());
        c.ports.push_back(btOutHeadphone);
        c.connectedProfiles[btOutHeadphone.id] = standardPcmAudioProfiles;

@@ -611,6 +598,9 @@ std::unique_ptr<Configuration> getBluetoothConfiguration() {
                createPort(c.nextPortId++, "BT A2DP Speaker", 0, false,
                           createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0,
                                           AudioDeviceDescription::CONNECTION_BT_A2DP));
        btOutSpeaker.profiles.insert(btOutSpeaker.profiles.begin(),
                                     standardPcmAudioProfiles.begin(),
                                     standardPcmAudioProfiles.end());
        c.ports.push_back(btOutSpeaker);
        c.connectedProfiles[btOutSpeaker.id] = standardPcmAudioProfiles;

@@ -623,20 +613,20 @@ std::unique_ptr<Configuration> getBluetoothConfiguration() {
                {createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {16000})});

        // Mix ports
        AudioPort btInMix =
                createPort(c.nextPortId++, "a2dp output", 0, true, createPortMixExt(1, 1));
        c.ports.push_back(btInMix);
        AudioPort btOutMix =
                createPort(c.nextPortId++, "a2dp output", 0, false, createPortMixExt(1, 1));
        c.ports.push_back(btOutMix);

        AudioPort btHeadsetInMix =
                createPort(c.nextPortId++, "hearing aid output", 0, true, createPortMixExt(1, 1));
        btHeadsetInMix.profiles.push_back(createProfile(
        AudioPort btHearingOutMix =
                createPort(c.nextPortId++, "hearing aid output", 0, false, createPortMixExt(1, 1));
        btHearingOutMix.profiles.push_back(createProfile(
                PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {16000, 24000}));
        c.ports.push_back(btHeadsetInMix);
        c.ports.push_back(btHearingOutMix);

        c.routes.push_back(createRoute({btInMix}, btOutDevice));
        c.routes.push_back(createRoute({btInMix}, btOutHeadphone));
        c.routes.push_back(createRoute({btInMix}, btOutSpeaker));
        c.routes.push_back(createRoute({btHeadsetInMix}, btOutHearingAid));
        c.routes.push_back(createRoute({btOutMix}, btOutDevice));
        c.routes.push_back(createRoute({btOutMix}, btOutHeadphone));
        c.routes.push_back(createRoute({btOutMix}, btOutSpeaker));
        c.routes.push_back(createRoute({btHearingOutMix}, btOutHearingAid));

        return c;
    }();
Loading