File indexing completed on 2025-01-19 06:44:38
0001 /* 0002 * BluezQt - Asynchronous Bluez wrapper library 0003 * 0004 * SPDX-FileCopyrightText: 2019 Manuel Weichselbaumer <mincequi@web.de> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "mediatransport_p.h" 0010 #include "a2dp-codecs.h" 0011 #include "macros.h" 0012 #include "utils.h" 0013 0014 namespace BluezQt 0015 { 0016 static MediaTransport::State stringToState(const QString &state) 0017 { 0018 if (state == QLatin1String("pending")) { 0019 return MediaTransport::State::Pending; 0020 } else if (state == QLatin1String("active")) { 0021 return MediaTransport::State::Active; 0022 } 0023 return MediaTransport::State::Idle; 0024 } 0025 0026 static AudioCodec intToCodec(int value) 0027 { 0028 switch (value) { 0029 case A2DP_CODEC_SBC: 0030 return AudioCodec::Sbc; 0031 break; 0032 case A2DP_CODEC_MPEG24: 0033 return AudioCodec::Aac; 0034 break; 0035 } 0036 0037 return AudioCodec::Invalid; 0038 } 0039 0040 static AudioSampleRate byteArrayToSampleRate(AudioCodec codec, const QByteArray &buffer) 0041 { 0042 switch (codec) { 0043 case AudioCodec::Sbc: { 0044 if (buffer.size() != sizeof(a2dp_sbc_t)) { 0045 return AudioSampleRate::Invalid; 0046 } 0047 0048 a2dp_sbc_t sbcConfig = *reinterpret_cast<const a2dp_sbc_t *>(buffer.constData()); 0049 switch (sbcConfig.frequency) { 0050 case SBC_SAMPLING_FREQ_44100: 0051 return AudioSampleRate::Rate44100; 0052 break; 0053 case SBC_SAMPLING_FREQ_48000: 0054 return AudioSampleRate::Rate48000; 0055 break; 0056 } 0057 break; 0058 } 0059 case AudioCodec::Aac: { 0060 if (buffer.size() != sizeof(a2dp_aac_t)) { 0061 return AudioSampleRate::Invalid; 0062 } 0063 0064 a2dp_aac_t aacConfig = *reinterpret_cast<const a2dp_aac_t *>(buffer.constData()); 0065 switch (AAC_GET_FREQUENCY(aacConfig)) { 0066 case AAC_SAMPLING_FREQ_44100: 0067 return AudioSampleRate::Rate44100; 0068 break; 0069 case AAC_SAMPLING_FREQ_48000: 0070 return AudioSampleRate::Rate48000; 0071 break; 0072 } 0073 break; 0074 } 0075 default: 0076 break; 0077 } 0078 0079 return AudioSampleRate::Invalid; 0080 } 0081 0082 MediaTransportPrivate::MediaTransportPrivate(const QString &path, const QVariantMap &properties) 0083 : QObject() 0084 , m_dbusInterface(Strings::orgBluez(), path, DBusConnection::orgBluez()) 0085 , m_dbusProperties(nullptr) 0086 , m_path(path) 0087 { 0088 DBusConnection::orgBluez().connect(Strings::orgBluez(), 0089 path, 0090 Strings::orgFreedesktopDBusProperties(), 0091 QStringLiteral("PropertiesChanged"), 0092 this, 0093 SLOT(onPropertiesChanged(QString, QVariantMap, QStringList))); 0094 init(properties); 0095 } 0096 0097 void MediaTransportPrivate::init(const QVariantMap &properties) 0098 { 0099 m_dbusProperties = new DBusProperties(Strings::orgBluez(), m_path, DBusConnection::orgBluez(), this); 0100 0101 m_volume = properties.value(QStringLiteral("Volume")).toUInt(); 0102 m_state = stringToState(properties.value(QStringLiteral("State")).toString()); 0103 m_configuration.codec = intToCodec(properties.value(QStringLiteral("Codec")).toInt()); 0104 m_configuration.sampleRate = byteArrayToSampleRate(m_configuration.codec, properties.value(QStringLiteral("Configuration")).toByteArray()); 0105 } 0106 0107 void MediaTransportPrivate::onPropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated) 0108 { 0109 if (interface != Strings::orgBluezMediaTransport1()) { 0110 return; 0111 } 0112 0113 for (auto it = changed.constBegin(); it != changed.constEnd(); ++it) { 0114 const QString &key = it.key(); 0115 const QVariant &value = it.value(); 0116 0117 if (key == QLatin1String("Volume")) { 0118 m_volume = value.toUInt(); 0119 Q_EMIT q.lock()->volumeChanged(m_volume); 0120 } else if (key == QLatin1String("State")) { 0121 m_state = stringToState(value.toString()); 0122 Q_EMIT q.lock()->stateChanged(m_state); 0123 } 0124 } 0125 0126 for (const QString &property : invalidated) { 0127 if (property == QLatin1String("Volume")) { 0128 m_volume = 0; 0129 Q_EMIT q.lock()->volumeChanged(m_volume); 0130 } else if (property == QLatin1String("State")) { 0131 PROPERTY_INVALIDATED(m_state, MediaTransport::State::Idle, stateChanged); 0132 } 0133 } 0134 } 0135 0136 } // namespace BluezQt 0137 0138 #include "moc_mediatransport_p.cpp"