blob: 9ec17766f54a36d07ad537b344ad64c2c6f59fe9 [file] [log] [blame]
Alice Kuo84e87672021-10-28 12:53:38 +08001/*
2 * Copyright 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BTAudioProviderLeAudio"
18
19#include "LeAudioAudioProvider.h"
20
21#include <android-base/logging.h>
22
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010023#include "AudioPort_2_0_to_2_2_Wrapper.h"
Alice Kuo84e87672021-10-28 12:53:38 +080024#include "BluetoothAudioSessionReport_2_2.h"
25#include "BluetoothAudioSupportedCodecsDB_2_1.h"
26
27namespace android {
28namespace hardware {
29namespace bluetooth {
30namespace audio {
31namespace V2_2 {
32namespace implementation {
33
34using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
35using ::android::hardware::Void;
36using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
37using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
38using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
39
40static constexpr uint32_t kBufferOutCount = 2; // two frame buffer
41static constexpr uint32_t kBufferInCount = 2; // two frame buffer
42
43LeAudioOutputAudioProvider::LeAudioOutputAudioProvider()
44 : LeAudioAudioProvider() {
45 session_type_ = V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
46}
47
48LeAudioInputAudioProvider::LeAudioInputAudioProvider()
49 : LeAudioAudioProvider() {
50 session_type_ = V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH;
51}
52
53LeAudioAudioProvider::LeAudioAudioProvider()
54 : BluetoothAudioProvider(), mDataMQ(nullptr) {}
55
56bool LeAudioAudioProvider::isValid(const V2_0::SessionType& sessionType) {
57 LOG(ERROR) << __func__ << ", invalid session type for Le Audio provider: "
58 << toString(sessionType);
59
60 return false;
61}
62
63bool LeAudioAudioProvider::isValid(const V2_1::SessionType& sessionType) {
64 return (sessionType == session_type_);
65}
66
67Return<void> LeAudioAudioProvider::startSession_2_1(
68 const sp<V2_0::IBluetoothAudioPort>& hostIf,
69 const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
70 if (audioConfig.getDiscriminator() !=
71 V2_1::AudioConfiguration::hidl_discriminator::pcmConfig) {
72 LOG(WARNING) << __func__
73 << " - Invalid Audio Configuration=" << toString(audioConfig);
74 _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
75 DataMQ::Descriptor());
76 return Void();
77 }
78
79 AudioConfiguration audioConfig_2_2;
80 audioConfig_2_2.pcmConfig(
81 {.sampleRate =
82 static_cast<V2_1::SampleRate>(audioConfig.pcmConfig().sampleRate),
83 .channelMode = audioConfig.pcmConfig().channelMode,
84 .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
85 .dataIntervalUs = 0});
86
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010087 sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
88 new AudioPort_2_0_to_2_2_Wrapper(hostIf);
89 return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
Alice Kuo84e87672021-10-28 12:53:38 +080090}
91
92Return<void> LeAudioAudioProvider::startSession_2_2(
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010093 const sp<V2_2::IBluetoothAudioPort>& hostIf,
Alice Kuo84e87672021-10-28 12:53:38 +080094 const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
95 /**
96 * Initialize the audio platform if audioConfiguration is supported.
97 * Save the IBluetoothAudioPort interface, so that it can be used
98 * later to send stream control commands to the HAL client, based on
99 * interaction with Audio framework.
100 */
101 if (audioConfig.getDiscriminator() !=
102 AudioConfiguration::hidl_discriminator::pcmConfig) {
103 LOG(WARNING) << __func__
104 << " - Invalid Audio Configuration=" << toString(audioConfig);
105 _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
106 DataMQ::Descriptor());
107 return Void();
108 } else if (!android::bluetooth::audio::IsSoftwarePcmConfigurationValid_2_1(
109 audioConfig.pcmConfig())) {
110 LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
111 << toString(audioConfig.pcmConfig());
112 _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
113 DataMQ::Descriptor());
114 return Void();
115 }
116
117 uint32_t kDataMqSize = 0;
118 switch (audioConfig.pcmConfig().sampleRate) {
119 case SampleRate::RATE_8000:
120 kDataMqSize = 8000;
121 break;
122 case SampleRate::RATE_16000:
123 kDataMqSize = 16000;
124 break;
125 case SampleRate::RATE_24000:
126 kDataMqSize = 24000;
127 break;
128 case SampleRate::RATE_32000:
129 kDataMqSize = 32000;
130 break;
131 case SampleRate::RATE_44100:
132 kDataMqSize = 44100;
133 break;
134 case SampleRate::RATE_48000:
135 kDataMqSize = 48000;
136 break;
137 default:
138 LOG(WARNING) << __func__ << " - Unsupported sampling frequency="
139 << toString(audioConfig.pcmConfig());
140 _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
141 DataMQ::Descriptor());
142 return Void();
143 }
144
145 /* Number of samples per millisecond */
146 kDataMqSize = ceil(kDataMqSize / 1000);
147
148 switch (audioConfig.pcmConfig().channelMode) {
149 case ChannelMode::MONO:
150 break;
151 case ChannelMode::STEREO:
152 kDataMqSize *= 2;
153 break;
154 default:
155 /* This should never happen it would be caught while validating
156 * parameters.
157 */
158 break;
159 }
160
161 switch (audioConfig.pcmConfig().bitsPerSample) {
162 case BitsPerSample::BITS_16:
163 kDataMqSize *= 2;
164 break;
165 case BitsPerSample::BITS_24:
166 kDataMqSize *= 3;
167 break;
168 case BitsPerSample::BITS_32:
169 kDataMqSize *= 4;
170 break;
171 default:
172 /* This should never happen it would be caught while validating
173 * parameters.
174 */
175 break;
176 }
177
178 if (session_type_ == V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH)
179 kDataMqSize *= kBufferOutCount;
180 else if (session_type_ ==
181 V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH)
182 kDataMqSize *= kBufferInCount;
183 else
184 LOG(WARNING) << __func__ << ", default single buffer used";
185
186 kDataMqSize *= audioConfig.pcmConfig().dataIntervalUs / 1000;
187
188 LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
189 << " byte(s)";
190
191 std::unique_ptr<DataMQ> tempDataMQ(
192 new DataMQ(kDataMqSize, /* EventFlag */ true));
193 if (tempDataMQ && tempDataMQ->isValid()) {
194 mDataMQ = std::move(tempDataMQ);
195 } else {
196 ALOGE_IF(!tempDataMQ, "failed to allocate data MQ");
197 ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "data MQ is invalid");
198 _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
199 return Void();
200 }
201
202 return BluetoothAudioProvider::startSession_2_2(hostIf, audioConfig,
203 _hidl_cb);
204}
205
206Return<void> LeAudioAudioProvider::onSessionReady(startSession_cb _hidl_cb) {
207 if (mDataMQ && mDataMQ->isValid()) {
208 BluetoothAudioSessionReport_2_2::OnSessionStarted(
209 session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
210 _hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
211 } else {
212 _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
213 }
214 return Void();
215}
216
217} // namespace implementation
218} // namespace V2_2
219} // namespace audio
220} // namespace bluetooth
221} // namespace hardware
222} // namespace android