2 * Copyright (C) 2016 The Qt Company Ltd.
3 * Copyright (C) 2016,2017 Konsulko Group
4 * Copyright (C) 2018 IoT.bzh
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include <QJsonObject>
26 Mixer::Mixer(QObject* parent)
29 connect(&m_client, SIGNAL(connected()), this, SLOT(onClientConnected()));
30 connect(&m_client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
31 connect(&m_client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onClientError(QAbstractSocket::SocketError)));
32 connect(&m_client, SIGNAL(eventReceived(QString, const QJsonValue&)), this, SLOT(onClientEventReceived(QString, const QJsonValue&)));
35 void Mixer::open(const QUrl& url)
41 QList<QObject*> Mixer::roles() const
46 void Mixer::setRoleVolume(AudioRole* role)
48 if (role == nullptr) return;
51 arg.insert("control", role->Name().toLocal8Bit().data());
52 arg.insert("value", QJsonValue(role->Value()));
54 m_client.call("audiomixer", "volume", arg);
57 void Mixer::parseControls(const QJsonValue & v)
59 qDebug() << "got controls: " << v;
61 for(QObject* role : m_roles) delete role;
64 for (const QJsonValue & av : v.toArray()) {
65 QString name = av.toObject()["control"].toString();
66 int value = av.toObject()["volume"].toDouble() * 100;
67 value = qBound(0, value, 100);
69 AudioRole *ar = new AudioRole(name, value);
70 connect(ar, SIGNAL(ValueChanged()), this, SLOT(onRoleValueChanged()));
73 qDebug() << "added role: " << ar->Name()
74 << " value: " << ar->Value();
80 void Mixer::onClientConnected()
82 m_client.call("audiomixer", "list_controls", QJsonObject(), [this](bool r, const QJsonValue& v) {
83 if (r && v.isObject()) {
84 parseControls(v.toObject()["response"]);
88 arg.insert("event", "controls_changed");
89 m_client.call("audiomixer", "subscribe", arg);
91 arg.insert("event", "volume_changed");
92 m_client.call("audiomixer", "subscribe", arg);
96 void Mixer::onClientDisconnected()
98 qDebug() << "Mixer::onClientDisconnected!";
99 QTimer::singleShot(1000, this, SLOT(TryOpen()));
102 void Mixer::onClientError(QAbstractSocket::SocketError se)
104 qDebug() << "Mixer::onClientError: " << se;
107 void Mixer::onClientEventReceived(QString eventName, const QJsonValue& data)
109 qDebug() << "Mixer::onClientEventReceived[" << eventName << "]: " << data;
111 if (eventName == "audiomixer/controls_changed") {
112 m_client.call("audiomixer", "list_controls", QJsonObject(), [this](bool r, const QJsonValue& v) {
113 if (r && v.isObject()) {
114 parseControls(v.toObject()["response"]);
118 else if (eventName == "audiomixer/volume_changed") {
119 QString name = data.toObject()["control"].toString();
120 int value = data.toObject()["value"].toDouble() * 100;
121 value = qBound(0, value, 100);
123 for (QObject *o : m_roles) {
124 AudioRole *ar = static_cast<AudioRole*>(o);
125 if (ar->Name() == name) {
134 void Mixer::onRoleValueChanged()
136 AudioRole* role = qobject_cast<AudioRole*>(QObject::sender());
137 if (role == nullptr) return;
139 /* if the role was not being updated by us, it was modified from the UI,
140 in which case we have to set it to the backend */
141 if (!role->EndUpdate())
145 void Mixer::TryOpen()
147 qDebug() << "Mixer::TryOpen: " << m_url;
148 m_client.open(m_url);