summaryrefslogtreecommitdiffstats
path: root/app/paclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/paclient.cpp')
-rw-r--r--app/paclient.cpp329
1 files changed, 0 insertions, 329 deletions
diff --git a/app/paclient.cpp b/app/paclient.cpp
deleted file mode 100644
index bd53cde..0000000
--- a/app/paclient.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2016,2017 Konsulko Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "paclient.h"
-
-#include <QtCore/QDebug>
-
-PaClient::PaClient()
- : m_init(false), m_ml(nullptr), m_mlapi(nullptr), m_ctx(nullptr)
-{
-}
-
-PaClient::~PaClient()
-{
- if (m_init)
- close();
-}
-
-void PaClient::close()
-{
- if (!m_init) return;
- pa_threaded_mainloop_stop(m_ml);
- pa_threaded_mainloop_free(m_ml);
- m_init = false;
-}
-
-static void set_sink_volume_cb(pa_context *c, int success, void *data)
-{
- Q_UNUSED(data);
-
- if (!success)
- qWarning() << "PaClient: set sink volume: " <<
- pa_strerror(pa_context_errno(c));
-}
-
-static void set_source_volume_cb(pa_context *c, int success, void *data)
-{
- Q_UNUSED(data);
-
- if (!success)
- qWarning() << "PaClient: set source volume: " <<
- pa_strerror(pa_context_errno(c));
-}
-
-void PaClient::setVolume(uint32_t type, uint32_t index, uint32_t channel, uint32_t volume)
-{
- pa_operation *o;
- pa_context *c = context();
- pa_cvolume *cvolume = NULL;
-
- if (type == C_SINK) {
- cvolume = m_sink_states.value(index);
- cvolume->values[channel] = volume;
- if (!(o = pa_context_set_sink_volume_by_index(c, index, cvolume, set_sink_volume_cb, NULL))) {
- qWarning() << "PaClient: set sink #" << index <<
- " channel #" << channel <<
- " volume: " << pa_strerror(pa_context_errno(c));
- return;
- }
- pa_operation_unref(o);
- } else if (type == C_SOURCE) {
- cvolume = m_source_states.value(index);
- cvolume->values[channel] = volume;
- if (!(o = pa_context_set_source_volume_by_index(c, index, cvolume, set_source_volume_cb, NULL))) {
- qWarning() << "PaClient: set source #" << index <<
- " channel #" << channel <<
- " volume: " << pa_strerror(pa_context_errno(c));
- return;
- }
- pa_operation_unref(o);
- }
-}
-
-void get_source_list_cb(pa_context *c,
- const pa_source_info *i,
- int eol,
- void *data)
-{
- int chan;
-
- PaClient *self = reinterpret_cast<PaClient*>(data);
-
- if (eol < 0) {
- qWarning() << "PaClient: get source list: " <<
- pa_strerror(pa_context_errno(c));
-
- self->close();
- return;
- }
-
- if (!eol) {
- self->addOneControlState(C_SOURCE, i->index, &i->volume);
- for (chan = 0; chan < i->channel_map.channels; chan++) {
- // NOTE: hide input control
- if (QString(i->name).endsWith("monitor"))
- continue;
-
- emit self->controlAdded(i->index, QString(i->name), QString(i->description),
- C_SOURCE, chan, channel_position_string[i->channel_map.map[chan]],
- i->volume.values[chan]);
- }
- }
-}
-
-void get_sink_list_cb(pa_context *c,
- const pa_sink_info *i,
- int eol,
- void *data)
-{
- PaClient *self = reinterpret_cast<PaClient*>(data);
- int chan;
-
- if(eol < 0) {
- qWarning() << "PaClient: get sink list: " <<
- pa_strerror(pa_context_errno(c));
- self->close();
- return;
- }
-
- if(!eol) {
- self->addOneControlState(C_SINK, i->index, &i->volume);
- for (chan = 0; chan < i->channel_map.channels; chan++) {
- emit self->controlAdded(i->index, QString(i->name), QString(i->description),
- C_SINK, chan, channel_position_string[i->channel_map.map[chan]],
- i->volume.values[chan]);
- }
- }
-}
-
-void get_sink_info_change_cb(pa_context *c,
- const pa_sink_info *i,
- int eol,
- void *data)
-{
- Q_UNUSED(c);
- Q_ASSERT(i);
- Q_ASSERT(data);
-
- if (eol) return;
-
- for (int chan = 0; chan < i->channel_map.channels; chan++) {
- PaClient *self = reinterpret_cast<PaClient*>(data);
- QHash<int, pa_cvolume *> states = self->sink_states();
- pa_cvolume *cvolume = states.value(i->index);
- // Check each channel for volume change
- if (cvolume->values[chan] != i->volume.values[chan]) {
- // On change, update cache and signal
- cvolume->values[chan] = i->volume.values[chan];
- emit self->volumeExternallyChanged(C_SINK, i->index, chan, i->volume.values[chan]);
- }
- }
-}
-
-void get_source_info_change_cb(pa_context *c,
- const pa_source_info *i,
- int eol,
- void *data)
-{
- Q_UNUSED(c);
- Q_ASSERT(i);
- Q_ASSERT(data);
-
- if (eol) return;
-
- for (int chan = 0; chan < i->channel_map.channels; chan++) {
- PaClient *self = reinterpret_cast<PaClient*>(data);
- QHash<int, pa_cvolume *> states = self->source_states();
- pa_cvolume *cvolume = states.value(i->index);
- // Check each channel for volume change
- if (cvolume->values[chan] != i->volume.values[chan]) {
- // On change, update cache and signal
- cvolume->values[chan] = i->volume.values[chan];
- emit self->volumeExternallyChanged(C_SOURCE, i->index, chan, i->volume.values[chan]);
- }
- }
-}
-
-
-void subscribe_cb(pa_context *c,
- pa_subscription_event_type_t type,
- uint32_t index,
- void *data)
-{
- pa_operation *o;
-
- if ((type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE) {
- qWarning("PaClient: unhandled subscribe event operation");
- return;
- }
-
- switch (type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
- case PA_SUBSCRIPTION_EVENT_SINK:
- if (!(o = pa_context_get_sink_info_by_index(c, index, get_sink_info_change_cb, data))) {
- qWarning() << "PaClient: get sink info by index: " <<
- pa_strerror(pa_context_errno(c));
- return;
- }
- break;
- case PA_SUBSCRIPTION_EVENT_SOURCE:
- if (!(o = pa_context_get_source_info_by_index(c, index, get_source_info_change_cb, data))) {
- qWarning() << "PaClient: get source info by index: " <<
- pa_strerror(pa_context_errno(c));
- return;
- }
- break;
- default:
- qWarning("PaClient: unhandled subscribe event facility");
- }
-}
-
-void context_state_cb(pa_context *c, void *data)
-{
- pa_operation *o;
- PaClient *self = reinterpret_cast<PaClient*>(data);
-
- switch (pa_context_get_state(c)) {
- case PA_CONTEXT_CONNECTING:
- case PA_CONTEXT_AUTHORIZING:
- case PA_CONTEXT_SETTING_NAME:
- break;
- case PA_CONTEXT_READY:
- // Fetch the controls of interest
- if (!(o = pa_context_get_source_info_list(c, get_source_list_cb, data))) {
- qWarning() << "PaClient: get source info list: " <<
- pa_strerror(pa_context_errno(c));
- return;
- }
- pa_operation_unref(o);
- if (!(o = pa_context_get_sink_info_list(c, &get_sink_list_cb, data))) {
- qWarning() << "PaClient: get sink info list: " <<
- pa_strerror(pa_context_errno(c));
- return;
- }
- pa_operation_unref(o);
- pa_context_set_subscribe_callback(c, subscribe_cb, data);
- if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t)(PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE), NULL, NULL))) {
- qWarning() << "PaClient: subscribe: " <<
- pa_strerror(pa_context_errno(c));
- return;
- }
- break;
- case PA_CONTEXT_TERMINATED:
- self->close();
- break;
-
- case PA_CONTEXT_FAILED:
- default:
- qCritical() << "PaClient: connection failed: " <<
- pa_strerror(pa_context_errno(c));
- self->close();
- break;
- }
-}
-
-void PaClient::init()
-{
- m_ml = pa_threaded_mainloop_new();
- if (!m_ml) {
- qCritical("PaClient: failed to create mainloop");
- return;
- }
-
- pa_threaded_mainloop_set_name(m_ml, "PaClient mainloop");
-
- m_mlapi = pa_threaded_mainloop_get_api(m_ml);
-
- lock();
-
- m_ctx = pa_context_new(m_mlapi, "Mixer");
- if (!m_ctx) {
- qCritical("PaClient: failed to create context");
- pa_threaded_mainloop_free(m_ml);
- return;
- }
- pa_context_set_state_callback(m_ctx, context_state_cb, this);
-
- if (pa_context_connect(m_ctx, 0, (pa_context_flags_t)0, 0) < 0) {
- qCritical("PaClient: failed to connect");
- pa_context_unref(m_ctx);
- pa_threaded_mainloop_free(m_ml);
- return;
- }
-
- if (pa_threaded_mainloop_start(m_ml) != 0) {
- qCritical("PaClient: failed to start mainloop");
- pa_context_unref(m_ctx);
- pa_threaded_mainloop_free(m_ml);
- return;
- }
-
- unlock();
-
- m_init = true;
-}
-
-void PaClient::addOneControlState(int type, int index, const pa_cvolume *cvolume)
-{
- pa_cvolume *cvolume_new = new pa_cvolume;
- cvolume_new->channels = cvolume->channels;
- for (int i = 0; i < cvolume->channels; i++)
- cvolume_new->values[i] = cvolume->values[i];
- if (type == C_SINK)
- m_sink_states.insert(index, cvolume_new);
- else if (type == C_SOURCE)
- m_source_states.insert(index, cvolume_new);
-}
-
-QHash<int, pa_cvolume *> PaClient::sink_states(void)
-{
- return m_sink_states;
-}
-
-QHash<int, pa_cvolume *> PaClient::source_states(void)
-{
- return m_source_states;
-}