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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/*
* BluezQt - Asynchronous Bluez wrapper library
*
* SPDX-FileCopyrightText: 2018 Manuel Weichselbaumer <mincequi@web.de>
*
* SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "mediaendpoint.h"
#include "a2dp-codecs.h"
#include "mediaendpoint_p.h"
namespace BluezQt
{
MediaEndpoint::MediaEndpoint(const Configuration &configuration, QObject *parent)
: QObject(parent)
, d(new MediaEndpointPrivate(configuration))
{
}
MediaEndpoint::~MediaEndpoint()
{
delete d;
}
QDBusObjectPath MediaEndpoint::objectPath() const
{
return d->m_objectPath;
}
const QVariantMap &MediaEndpoint::properties() const
{
return d->m_properties;
}
void MediaEndpoint::setConfiguration(const QString &transportObjectPath, const QVariantMap &properties)
{
Q_EMIT configurationSet(transportObjectPath, properties);
}
void MediaEndpoint::selectConfiguration(const QByteArray &capabilities, const Request<QByteArray> &request)
{
switch (d->m_configuration.codec) {
case MediaEndpoint::Codec::Sbc: {
if (capabilities.size() != sizeof(a2dp_sbc_t)) {
Q_EMIT configurationSelected(capabilities, QByteArray());
request.reject();
return;
}
a2dp_sbc_t caps = *reinterpret_cast<const a2dp_sbc_t *>(capabilities.constData());
if (caps.frequency & SBC_SAMPLING_FREQ_44100) {
caps.frequency = SBC_SAMPLING_FREQ_44100;
} else if (caps.frequency & SBC_SAMPLING_FREQ_48000) {
caps.frequency = SBC_SAMPLING_FREQ_48000;
} else {
break;
}
if (caps.channel_mode & SBC_CHANNEL_MODE_STEREO) {
caps.channel_mode = SBC_CHANNEL_MODE_STEREO;
} else if (caps.channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO) {
caps.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
} else {
break;
}
if (caps.block_length & SBC_BLOCK_LENGTH_16) {
caps.block_length = SBC_BLOCK_LENGTH_16;
} else if (caps.block_length & SBC_BLOCK_LENGTH_12) {
caps.block_length = SBC_BLOCK_LENGTH_12;
} else if (caps.block_length & SBC_BLOCK_LENGTH_8) {
caps.block_length = SBC_BLOCK_LENGTH_8;
} else if (caps.block_length & SBC_BLOCK_LENGTH_4) {
caps.block_length = SBC_BLOCK_LENGTH_4;
} else {
break;
}
if (caps.subbands & SBC_SUBBANDS_8) {
caps.subbands = SBC_SUBBANDS_8;
} else if (caps.subbands & SBC_SUBBANDS_4) {
caps.subbands = SBC_SUBBANDS_4;
} else {
break;
}
if (caps.allocation_method & SBC_ALLOCATION_LOUDNESS) {
caps.allocation_method = SBC_ALLOCATION_LOUDNESS;
} else if (caps.allocation_method & SBC_ALLOCATION_SNR) {
caps.allocation_method = SBC_ALLOCATION_SNR;
} else {
break;
}
caps.min_bitpool = 2;
caps.max_bitpool = 53;
const QByteArray configuration(reinterpret_cast<const char *>(&caps), sizeof(caps));
Q_EMIT configurationSelected(capabilities, configuration);
request.accept(configuration);
return;
break;
}
case MediaEndpoint::Codec::Aac:
if (capabilities.size() != sizeof(a2dp_aac_t)) {
Q_EMIT configurationSelected(capabilities, QByteArray());
request.reject();
return;
}
// TODO: implement AAC. However selectConfiguration seems not to be used by iOS nor Android.
Q_EMIT configurationSelected(capabilities, QByteArray());
request.reject();
return;
break;
}
Q_EMIT configurationSelected(capabilities, QByteArray());
request.reject();
}
void MediaEndpoint::clearConfiguration(const QString &transportObjectPath)
{
Q_EMIT configurationCleared(transportObjectPath);
}
void MediaEndpoint::release()
{
}
} // namespace BluezQt
#include "moc_mediaendpoint.cpp"
|