BluezQt

mediaendpoint.cpp
1 /*
2  * BluezQt - Asynchronous Bluez wrapper library
3  *
4  * SPDX-FileCopyrightText: 2018 Manuel Weichselbaumer <[email protected]>
5  *
6  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7  */
8 
9 #include "mediaendpoint.h"
10 #include "a2dp-codecs.h"
11 #include "mediaendpoint_p.h"
12 
13 namespace BluezQt
14 {
15 MediaEndpoint::MediaEndpoint(const Configuration &configuration, QObject *parent)
16  : QObject(parent)
17  , d(new MediaEndpointPrivate(configuration))
18 {
19 }
20 
22 {
23  delete d;
24 }
25 
27 {
28  return d->m_objectPath;
29 }
30 
31 const QVariantMap &MediaEndpoint::properties() const
32 {
33  return d->m_properties;
34 }
35 
36 void MediaEndpoint::setConfiguration(const QString &transportObjectPath, const QVariantMap &properties)
37 {
38  Q_EMIT configurationSet(transportObjectPath, properties);
39 }
40 
41 void MediaEndpoint::selectConfiguration(const QByteArray &capabilities, const Request<QByteArray> &request)
42 {
43  switch (d->m_configuration.codec) {
44  case MediaEndpoint::Codec::Sbc: {
45  if (capabilities.size() != sizeof(a2dp_sbc_t)) {
46  Q_EMIT configurationSelected(capabilities, QByteArray());
47  request.reject();
48  return;
49  }
50 
51  a2dp_sbc_t caps = *reinterpret_cast<const a2dp_sbc_t *>(capabilities.constData());
52  if (caps.frequency & SBC_SAMPLING_FREQ_44100) {
53  caps.frequency = SBC_SAMPLING_FREQ_44100;
54  } else if (caps.frequency & SBC_SAMPLING_FREQ_48000) {
55  caps.frequency = SBC_SAMPLING_FREQ_48000;
56  } else {
57  break;
58  }
59 
60  if (caps.channel_mode & SBC_CHANNEL_MODE_STEREO) {
61  caps.channel_mode = SBC_CHANNEL_MODE_STEREO;
62  } else if (caps.channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO) {
63  caps.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
64  } else {
65  break;
66  }
67 
68  if (caps.block_length & SBC_BLOCK_LENGTH_16) {
69  caps.block_length = SBC_BLOCK_LENGTH_16;
70  } else if (caps.block_length & SBC_BLOCK_LENGTH_12) {
71  caps.block_length = SBC_BLOCK_LENGTH_12;
72  } else if (caps.block_length & SBC_BLOCK_LENGTH_8) {
73  caps.block_length = SBC_BLOCK_LENGTH_8;
74  } else if (caps.block_length & SBC_BLOCK_LENGTH_4) {
75  caps.block_length = SBC_BLOCK_LENGTH_4;
76  } else {
77  break;
78  }
79 
80  if (caps.subbands & SBC_SUBBANDS_8) {
81  caps.subbands = SBC_SUBBANDS_8;
82  } else if (caps.subbands & SBC_SUBBANDS_4) {
83  caps.subbands = SBC_SUBBANDS_4;
84  } else {
85  break;
86  }
87 
88  if (caps.allocation_method & SBC_ALLOCATION_LOUDNESS) {
89  caps.allocation_method = SBC_ALLOCATION_LOUDNESS;
90  } else if (caps.allocation_method & SBC_ALLOCATION_SNR) {
91  caps.allocation_method = SBC_ALLOCATION_SNR;
92  } else {
93  break;
94  }
95 
96  caps.min_bitpool = 2;
97  caps.max_bitpool = 53;
98 
99  const QByteArray configuration(reinterpret_cast<const char *>(&caps), sizeof(caps));
100  Q_EMIT configurationSelected(capabilities, configuration);
101  request.accept(configuration);
102  return;
103 
104  break;
105  }
106  case MediaEndpoint::Codec::Aac:
107  if (capabilities.size() != sizeof(a2dp_aac_t)) {
108  Q_EMIT configurationSelected(capabilities, QByteArray());
109  request.reject();
110  return;
111  }
112 
113  // TODO: implement AAC. However selectConfiguration seems not to be used by iOS nor Android.
114  Q_EMIT configurationSelected(capabilities, QByteArray());
115  request.reject();
116  return;
117 
118  break;
119  }
120 
121  Q_EMIT configurationSelected(capabilities, QByteArray());
122  request.reject();
123 }
124 
125 void MediaEndpoint::clearConfiguration(const QString &transportObjectPath)
126 {
127  Q_EMIT configurationCleared(transportObjectPath);
128 }
129 
131 {
132 }
133 
134 } // namespace BluezQt
135 
136 #include "moc_mediaendpoint.cpp"
virtual void selectConfiguration(const QByteArray &capabilities, const Request< QByteArray > &request)
Select preferable configuration from the supported capabilities.
virtual void setConfiguration(const QString &transportObjectPath, const QVariantMap &properties)
Set configuration for the transport.
Configuration for MediaEndpoint construction.
Definition: mediaendpoint.h:47
Q_EMITQ_EMIT
~MediaEndpoint() override
Destroys a MediaEndpoint object.
void configurationSelected(const QByteArray &capabilities, const QByteArray &configuration)
Indicates that configuration was selected.
virtual void release()
Indicates that the MediaEndpoint was unregistered.
virtual const QVariantMap & properties() const
Properties of the endpoint.
void configurationCleared(const QString &transportObjectPath)
Indicates that configuration was cleared for transport.
void accept(T returnValue) const
Accepts the request.
Definition: request.cpp:126
virtual void clearConfiguration(const QString &transportObjectPath)
Clear transport configuration.
void configurationSet(const QString &transportObjectPath, const QVariantMap &properties)
Indicates that configuration was set for transport.
virtual QDBusObjectPath objectPath() const
D-Bus object path of the MediaEndpoint.
MediaEndpoint(const Configuration &configuration, QObject *parent=nullptr)
Creates a new MediaEndpoint object.
void reject() const
Rejects the request.
Definition: request.cpp:132
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Sep 27 2023 04:04:48 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.