File indexing completed on 2024-12-01 08:10:18

0001 /*
0002     SPDX-FileCopyrightText: 2008 Helio Chissini de Castro <helio@kde.org>
0003     SPDX-FileCopyrightText: 2016 David Rosca <nowrep@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "volumefeedback.h"
0009 #include "canberracontext.h"
0010 #include "soundthemeconfig.h"
0011 
0012 VolumeFeedback::VolumeFeedback(QObject *parent)
0013     : QObject(parent)
0014     , m_config(new SoundThemeConfig(this))
0015 {
0016     QPulseAudio::CanberraContext::instance()->ref();
0017     if (ca_context_set_driver(QPulseAudio::CanberraContext::instance()->canberra(), "pulse") != CA_SUCCESS) {
0018         return;
0019     }
0020 
0021     connect(m_config, &SoundThemeConfig::soundThemeChanged, this, &VolumeFeedback::updateCachedSound);
0022     updateCachedSound();
0023 }
0024 
0025 VolumeFeedback::~VolumeFeedback()
0026 {
0027     QPulseAudio::CanberraContext::instance()->unref();
0028 }
0029 
0030 bool VolumeFeedback::isValid() const
0031 {
0032     return QPulseAudio::CanberraContext::instance()->canberra();
0033 }
0034 
0035 void VolumeFeedback::play(quint32 sinkIndex)
0036 {
0037     auto context = QPulseAudio::CanberraContext::instance()->canberra();
0038 
0039     if (!context) {
0040         return;
0041     }
0042 
0043     int playing = 0;
0044     const int cindex = 2; // Note "2" is simply the index we've picked. It's somewhat irrelevant.
0045     ca_context_playing(context, cindex, &playing);
0046 
0047     // NB Depending on how this is desired to work, we may want to simply
0048     // skip playing, or cancel the currently playing sound and play our
0049     // new one... for now, let's do the latter.
0050     if (playing) {
0051         ca_context_cancel(context, cindex);
0052     }
0053 
0054     char dev[64];
0055     snprintf(dev, sizeof(dev), "%lu", (unsigned long)sinkIndex);
0056     ca_context_change_device(context, dev);
0057 
0058     // Ideally we'd use something like ca_gtk_play_for_widget()...
0059     /* clang-format off */
0060     ca_context_play(context, cindex,
0061                     CA_PROP_EVENT_ID, "audio-volume-change",
0062                     CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", // For better performance
0063                     nullptr);
0064     /* clang-format on */
0065 
0066     ca_context_change_device(context, nullptr);
0067 }
0068 
0069 void VolumeFeedback::updateCachedSound()
0070 {
0071     auto context = QPulseAudio::CanberraContext::instance()->canberra();
0072     if (!context) {
0073         return;
0074     }
0075 
0076     /* clang-format off */
0077     ca_context_cache(context,
0078                      CA_PROP_EVENT_DESCRIPTION, "Volume Control Feedback Sound",
0079                      CA_PROP_EVENT_ID, "audio-volume-change",
0080                      CA_PROP_CANBERRA_ENABLE, "1",
0081                      CA_PROP_CANBERRA_XDG_THEME_NAME, m_config->soundTheme().toLatin1().constData(),
0082                      nullptr);
0083     /* clang-format on */
0084 }