~ubuntu-branches/ubuntu/trusty/phonon/trusty-updates

« back to all changes in this revision

Viewing changes to phonon/pulsesupport.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Modestas Vainius
  • Date: 2011-03-11 21:39:20 UTC
  • mfrom: (6.1.4 experimental)
  • Revision ID: james.westby@ubuntu.com-20110311213920-pvkmqc1gdpy88uzx
Tags: 4:4.6.0really4.4.4-2
* Drop phonon-backends-dbg from phonon-dbg Recommends/Breaks. No longer
  needed.
* Readd packaging copyright/licensing to debian/copyright.
* Bump libphonon-dev Breaks/Replaces to << 4:4.6.0really4.4.4 for
  libphononexperimental-dev. experimental/avcaptureinterface.h header which
  used to be there up to 4.4.4 (see changelog below).
* Switch debian/rules build engine to dhmk (qt-kde-team/2/*):
  - build-depend on pkg-kde-tools >= 0.11;
  - port debian/rules to dhmk keeping it dh compatible as much as possible.
* Drop unused ${shlibs:Depends} from libphonon-dev and
  libphononexperimental-dev packages.
* Add README.Debian to phonon-backend-null package.
* Remove phonon-backend-null.lintian-overrides: phonon-backend-null is no
  longer and empty package due to README.Debian (see above).
* Release to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <QtCore/QAbstractEventDispatcher>
24
24
#include <QtCore/QDebug>
25
25
#include <QtCore/QStringList>
26
 
#include <QTimer>
 
26
#include <QtCore/QTimer>
 
27
#include <QtCore/QMutex>
27
28
 
28
29
#ifdef HAVE_PULSEAUDIO
29
30
#include "pulsestream_p.h"
43
44
namespace Phonon
44
45
{
45
46
 
 
47
QMutex probeMutex;
46
48
static PulseSupport* s_instance = NULL;
47
49
 
48
50
#ifdef HAVE_PULSEAUDIO
57
59
    static int level = -1;
58
60
    if (level < 1) {
59
61
        level = 0;
60
 
        QString pulseenv = qgetenv("PHONON_PULSEAUDIO_DEBUG");
 
62
        QByteArray pulseenv = qgetenv("PHONON_PULSEAUDIO_DEBUG");
61
63
        int l = pulseenv.toInt();
62
64
        if (l > 0)
63
65
            level = (l > 2 ? 2 : l);
72
74
        QString output;
73
75
        if (obj) {
74
76
            // Strip away namespace from className
75
 
            QString className(obj->metaObject()->className());
 
77
            QByteArray className(obj->metaObject()->className());
76
78
            int nameLength = className.length() - className.lastIndexOf(':') - 1;
77
79
            className = className.right(nameLength);
78
 
            output.sprintf("%s %s (%s %p)", message.toLatin1().constData(), 
79
 
                           obj->objectName().toLatin1().constData(), 
80
 
                           className.toLatin1().constData(), obj);
 
80
            output.sprintf("%s %s (%s %p)", message.toLatin1().constData(),
 
81
                           obj->objectName().toLatin1().constData(),
 
82
                           className.constData(), obj);
81
83
        }
82
84
        else {
83
85
            output = message;
84
86
        }
85
87
        if (priority <= debugLevel()) {
86
 
            qDebug() << QString("PulseSupport(%1): %2").arg(priority).arg(output);
 
88
            qDebug() << QString::fromLatin1("PulseSupport(%1): %2").arg(priority).arg(output);
87
89
        }
88
90
    }
89
91
}
97
99
        : pulseName(name), pulseIndex(index)
98
100
        {
99
101
            properties["name"] = desc;
100
 
            properties["description"] = ""; // We don't have descriptions (well we do, but we use them as the name!)
 
102
            properties["description"] = QLatin1String(""); // We don't have descriptions (well we do, but we use them as the name!)
101
103
            properties["icon"] = icon;
102
104
            properties["available"] = (index != PA_INVALID_INDEX);
103
105
            properties["isAdvanced"] = false; // Nothing is advanced!
 
106
 
 
107
            DeviceAccessList dal;
 
108
            dal.append(DeviceAccess("pulse", desc));
 
109
            properties["deviceAccessList"] = QVariant::fromValue<DeviceAccessList>(dal);
104
110
        }
105
111
 
106
112
        // Needed for QMap
118
124
class PulseUserData
119
125
{
120
126
    public:
121
 
        inline 
 
127
        inline
122
128
        PulseUserData()
123
129
        {
124
130
        }
168
174
    s_outputDevices.clear();
169
175
    s_outputDevicePriorities.clear();
170
176
    index = s_deviceIndexCounter++;
171
 
    s_outputDeviceIndexes.insert("sink:default", index);
172
 
    s_outputDevices.insert(index, AudioDevice("sink:default", QObject::tr("PulseAudio Sound Server"), "audio-backend-pulseaudio", 0));
 
177
    s_outputDeviceIndexes.insert(QLatin1String("sink:default"), index);
 
178
    s_outputDevices.insert(index, AudioDevice(QLatin1String("sink:default"), QObject::tr("PulseAudio Sound Server"), QLatin1String("audio-backend-pulseaudio"), 0));
173
179
    for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) {
174
180
        Phonon::Category cat = static_cast<Phonon::Category>(i);
175
181
        s_outputDevicePriorities[cat].insert(0, index);
179
185
    s_captureDevices.clear();
180
186
    s_captureDevicePriorities.clear();
181
187
    index = s_deviceIndexCounter++;
182
 
    s_captureDeviceIndexes.insert("source:default", index);
183
 
    s_captureDevices.insert(index, AudioDevice("source:default", QObject::tr("PulseAudio Sound Server"), "audio-backend-pulseaudio", 0));
 
188
    s_captureDeviceIndexes.insert(QLatin1String("source:default"), index);
 
189
    s_captureDevices.insert(index, AudioDevice(QLatin1String("source:default"), QObject::tr("PulseAudio Sound Server"), QLatin1String("audio-backend-pulseaudio"), 0));
184
190
    for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) {
185
191
        Phonon::Category cat = static_cast<Phonon::Category>(i);
186
192
        s_captureDevicePriorities[cat].insert(0, index);
195
201
    PulseUserData *u = reinterpret_cast<PulseUserData*>(userdata);
196
202
 
197
203
    if (eol < 0) {
198
 
        logMessage(QString("Failed to initialize device manager extension: %1").arg(pa_strerror(pa_context_errno(c))));
 
204
        logMessage(QString::fromLatin1("Failed to initialize device manager extension: %1").arg(pa_strerror(pa_context_errno(c))));
199
205
        if (s_context != c) {
200
 
            logMessage("Falling back to single device mode");
 
206
            logMessage(QLatin1String("Falling back to single device mode"));
201
207
            // Only create our gerneric devices during the probe phase.
202
208
            createGenericDevices();
203
209
            // As this is our probe phase, exit immediately
392
398
    pa_operation *o;
393
399
    PulseUserData *u = new PulseUserData;
394
400
    if (!(o = pa_ext_device_manager_read(c, ext_device_manager_read_cb, u))) {
395
 
        logMessage(QString("pa_ext_device_manager_read() failed."));
 
401
        logMessage(QString::fromLatin1("pa_ext_device_manager_read() failed."));
396
402
        delete u;
397
403
        return;
398
404
    }
408
414
        if (pa_context_errno(c) == PA_ERR_NOENTITY)
409
415
            return;
410
416
 
411
 
        logMessage(QString("Sink input callback failure"));
 
417
        logMessage(QLatin1String("Sink input callback failure"));
412
418
        return;
413
419
    }
414
420
 
420
426
    // loop through (*i) and extract phonon->streamindex...
421
427
    const char *t;
422
428
    if ((t = pa_proplist_gets(i->proplist, "phonon.streamid"))) {
423
 
        logMessage(QString("Found PulseAudio stream index %1 for Phonon Output Stream %2").arg(i->index).arg(t));
 
429
        logMessage(QString::fromLatin1("Found PulseAudio stream index %1 for Phonon Output Stream %2").arg(i->index).arg(QLatin1String(t)));
424
430
 
425
431
        // We only care about our own streams (other phonon processes are irrelevent)
426
 
        if (s_outputStreams.contains(QString(t))) {
 
432
        if (s_outputStreams.contains(QLatin1String(t))) {
427
433
            PulseStream *stream = s_outputStreams[QString(t)];
428
434
            stream->setIndex(i->index);
429
435
            stream->setVolume(&i->volume);
451
457
        if (pa_context_errno(c) == PA_ERR_NOENTITY)
452
458
            return;
453
459
 
454
 
        logMessage(QString("Source output callback failure"));
 
460
        logMessage(QLatin1String("Source output callback failure"));
455
461
        return;
456
462
    }
457
463
 
463
469
    // loop through (*i) and extract phonon->streamindex...
464
470
    const char *t;
465
471
    if ((t = pa_proplist_gets(i->proplist, "phonon.streamid"))) {
466
 
        logMessage(QString("Found PulseAudio stream index %1 for Phonon Capture Stream %2").arg(i->index).arg(t));
 
472
        logMessage(QString::fromLatin1("Found PulseAudio stream index %1 for Phonon Capture Stream %2").arg(i->index).arg(QLatin1String(t)));
467
473
 
468
474
        // We only care about our own streams (other phonon processes are irrelevent)
469
 
        if (s_captureStreams.contains(QString(t))) {
 
475
        if (s_captureStreams.contains(QLatin1String(t))) {
470
476
            PulseStream *stream = s_captureStreams[QString(t)];
471
477
            stream->setIndex(i->index);
472
478
            //stream->setVolume(&i->volume);
494
500
            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
495
501
                PulseStream *stream = findStreamByPulseIndex(s_outputStreams, index);
496
502
                if (stream) {
497
 
                    logMessage(QString("Phonon Output Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(stream->uuid()));
 
503
                    logMessage(QString::fromLatin1("Phonon Output Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(stream->uuid()));
498
504
                    stream->setIndex(PA_INVALID_INDEX);
499
505
                }
500
506
            } else {
501
507
                pa_operation *o;
502
508
                if (!(o = pa_context_get_sink_input_info(c, index, sink_input_cb, NULL))) {
503
 
                    logMessage(QString("pa_context_get_sink_input_info() failed"));
 
509
                    logMessage(QString::fromLatin1("pa_context_get_sink_input_info() failed"));
504
510
                    return;
505
511
                }
506
512
                pa_operation_unref(o);
511
517
            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
512
518
              PulseStream *stream = findStreamByPulseIndex(s_captureStreams, index);
513
519
              if (stream) {
514
 
                    logMessage(QString("Phonon Capture Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(stream->uuid()));
 
520
                    logMessage(QString::fromLatin1("Phonon Capture Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(stream->uuid()));
515
521
                    stream->setIndex(PA_INVALID_INDEX);
516
522
                }
517
523
            } else {
518
524
                pa_operation *o;
519
525
                if (!(o = pa_context_get_source_output_info(c, index, source_output_cb, NULL))) {
520
 
                    logMessage(QString("pa_context_get_sink_input_info() failed"));
 
526
                    logMessage(QString::fromLatin1("pa_context_get_sink_input_info() failed"));
521
527
                    return;
522
528
                }
523
529
                pa_operation_unref(o);
527
533
}
528
534
 
529
535
 
530
 
static const char* statename(pa_context_state_t state)
 
536
static QString statename(pa_context_state_t state)
531
537
{
532
538
    switch (state)
533
539
    {
534
 
        case PA_CONTEXT_UNCONNECTED:  return "Unconnected";
535
 
        case PA_CONTEXT_CONNECTING:   return "Connecting";
536
 
        case PA_CONTEXT_AUTHORIZING:  return "Authorizing";
537
 
        case PA_CONTEXT_SETTING_NAME: return "Setting Name";
538
 
        case PA_CONTEXT_READY:        return "Ready";
539
 
        case PA_CONTEXT_FAILED:       return "Failed";
540
 
        case PA_CONTEXT_TERMINATED:   return "Terminated";
 
540
        case PA_CONTEXT_UNCONNECTED:  return QLatin1String("Unconnected");
 
541
        case PA_CONTEXT_CONNECTING:   return QLatin1String("Connecting");
 
542
        case PA_CONTEXT_AUTHORIZING:  return QLatin1String("Authorizing");
 
543
        case PA_CONTEXT_SETTING_NAME: return QLatin1String("Setting Name");
 
544
        case PA_CONTEXT_READY:        return QLatin1String("Ready");
 
545
        case PA_CONTEXT_FAILED:       return QLatin1String("Failed");
 
546
        case PA_CONTEXT_TERMINATED:   return QLatin1String("Terminated");
541
547
    }
542
548
 
543
 
    static QString unknown;
544
 
    unknown = QString("Unknown state: %0").arg(state);
545
 
    return unknown.toAscii().constData();
 
549
    return QString::fromLatin1("Unknown state: %0").arg(state);
546
550
}
547
551
 
548
552
static void context_state_callback(pa_context *c, void *)
549
553
{
550
554
    Q_ASSERT(c);
551
555
 
552
 
    logMessage(QString("context_state_callback %1").arg(statename(pa_context_get_state(c))));
 
556
    logMessage(QString::fromLatin1("context_state_callback %1").arg(statename(pa_context_get_state(c))));
553
557
    pa_context_state_t state = pa_context_get_state(c);
554
558
    if (state == PA_CONTEXT_READY) {
555
559
        // We've connected to PA, so it is active
565
569
            if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t)
566
570
                                              (PA_SUBSCRIPTION_MASK_SINK_INPUT|
567
571
                                               PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT), NULL, NULL))) {
568
 
                logMessage(QString("pa_context_subscribe() failed"));
 
572
                logMessage(QLatin1String("pa_context_subscribe() failed"));
569
573
                return;
570
574
            }
571
575
            pa_operation_unref(o);
575
579
            // and then load up info about all streams.
576
580
            for (QMap<QString, PulseStream*>::iterator it = s_outputStreams.begin(); it != s_outputStreams.end(); ++it) {
577
581
              PulseStream *stream = *it;
578
 
              logMessage(QString("Phonon Output Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(stream->uuid()));
 
582
              logMessage(QString::fromLatin1("Phonon Output Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(stream->uuid()));
579
583
              stream->setIndex(PA_INVALID_INDEX);
580
584
            }
581
585
            if (!(o = pa_context_get_sink_input_info_list(c, sink_input_cb, NULL))) {
582
 
              logMessage(QString("pa_context_get_sink_input_info_list() failed"));
 
586
              logMessage(QString::fromLatin1("pa_context_get_sink_input_info_list() failed"));
583
587
              return;
584
588
            }
585
589
            pa_operation_unref(o);
586
590
 
587
591
            for (QMap<QString, PulseStream*>::iterator it = s_captureStreams.begin(); it != s_captureStreams.end(); ++it) {
588
592
              PulseStream *stream = *it;
589
 
              logMessage(QString("Phonon Capture Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(stream->uuid()));
 
593
              logMessage(QString::fromLatin1("Phonon Capture Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(stream->uuid()));
590
594
              stream->setIndex(PA_INVALID_INDEX);
591
595
            }
592
596
            if (!(o = pa_context_get_source_output_info_list(c, source_output_cb, NULL))) {
593
 
              logMessage(QString("pa_context_get_source_output_info_list() failed"));
 
597
              logMessage(QString::fromLatin1("pa_context_get_source_output_info_list() failed"));
594
598
              return;
595
599
            }
596
600
            pa_operation_unref(o);
601
605
        if (s_context == c) {
602
606
            pa_ext_device_manager_set_subscribe_cb(c, ext_device_manager_subscribe_cb, NULL);
603
607
            if (!(o = pa_ext_device_manager_subscribe(c, 1, NULL, NULL))) {
604
 
                logMessage(QString("pa_ext_device_manager_subscribe() failed"));
 
608
                logMessage(QString::fromLatin1("pa_ext_device_manager_subscribe() failed"));
605
609
                return;
606
610
            }
607
611
            pa_operation_unref(o);
611
615
        PulseUserData *u = new PulseUserData;
612
616
        if (!(o = pa_ext_device_manager_read(c, ext_device_manager_read_cb, u))) {
613
617
            if (s_context != c) {
614
 
                logMessage(QString("pa_ext_device_manager_read() failed. Attempting to continue without device manager support"));
 
618
                logMessage(QString::fromLatin1("pa_ext_device_manager_read() failed. Attempting to continue without device manager support"));
615
619
                // Only create our gerneric devices during the probe phase.
616
620
                createGenericDevices();
617
621
                // As this is our probe phase, exit immediately
653
657
PulseSupport* PulseSupport::getInstance()
654
658
{
655
659
    if (NULL == s_instance) {
656
 
        s_instance = new PulseSupport();
 
660
        /*
 
661
         * In order to prevent the instance being used from multiple threads
 
662
         * prior to it being contructed fully, we need to ensure we obtain a
 
663
         * lock prior to creating it. After we aquire the lock, check to see
 
664
         * if the object is created again before proceeding.
 
665
         */
 
666
        probeMutex.lock();
 
667
        if (NULL == s_instance)
 
668
            s_instance = new PulseSupport();
 
669
        probeMutex.unlock();
657
670
    }
658
671
    return s_instance;
659
672
}
669
682
void PulseSupport::debug()
670
683
{
671
684
#ifdef HAVE_PULSEAUDIO
672
 
    logMessage(QString("Have we been initialised yet? %1").arg(s_instance ? "Yes" : "No"));
 
685
    logMessage(QString::fromLatin1("Have we been initialised yet? %1").arg(s_instance ? "Yes" : "No"));
673
686
    if (s_instance) {
674
 
        logMessage(QString("Connected to PulseAudio? %1").arg(s_pulseActive ? "Yes" : "No"));
675
 
        logMessage(QString("PulseAudio support 'Active'? %1").arg(s_instance->isActive() ? "Yes" : "No"));
 
687
        logMessage(QString::fromLatin1("Connected to PulseAudio? %1").arg(s_pulseActive ? "Yes" : "No"));
 
688
        logMessage(QString::fromLatin1("PulseAudio support 'Active'? %1").arg(s_instance->isActive() ? "Yes" : "No"));
676
689
    }
677
690
#endif
678
691
}
682
695
{
683
696
#ifdef HAVE_PULSEAUDIO
684
697
    // Initialise our map (is there a better way to do this?)
685
 
    s_roleCategoryMap["none"] = Phonon::NoCategory;
686
 
    s_roleCategoryMap["video"] = Phonon::VideoCategory;
687
 
    s_roleCategoryMap["music"] = Phonon::MusicCategory;
688
 
    s_roleCategoryMap["game"] = Phonon::GameCategory;
689
 
    s_roleCategoryMap["event"] = Phonon::NotificationCategory;
690
 
    s_roleCategoryMap["phone"] = Phonon::CommunicationCategory;
691
 
    //s_roleCategoryMap["animation"]; // No Mapping
692
 
    //s_roleCategoryMap["production"]; // No Mapping
693
 
    s_roleCategoryMap["a11y"] = Phonon::AccessibilityCategory;
 
698
    s_roleCategoryMap[QLatin1String("none")] = Phonon::NoCategory;
 
699
    s_roleCategoryMap[QLatin1String("video")] = Phonon::VideoCategory;
 
700
    s_roleCategoryMap[QLatin1String("music")] = Phonon::MusicCategory;
 
701
    s_roleCategoryMap[QLatin1String("game")] = Phonon::GameCategory;
 
702
    s_roleCategoryMap[QLatin1String("event")] = Phonon::NotificationCategory;
 
703
    s_roleCategoryMap[QLatin1String("phone")] = Phonon::CommunicationCategory;
 
704
    //s_roleCategoryMap[QLatin1String("animation")]; // No Mapping
 
705
    //s_roleCategoryMap[QLatin1String("production")]; // No Mapping
 
706
    s_roleCategoryMap[QLatin1String("a11y")] = Phonon::AccessibilityCategory;
694
707
 
695
708
    // To allow for easy debugging, give an easy way to disable this pulseaudio check
696
 
    QString pulseenv = qgetenv("PHONON_PULSEAUDIO_DISABLE");
 
709
    QByteArray pulseenv = qgetenv("PHONON_PULSEAUDIO_DISABLE");
697
710
    if (pulseenv.toInt()) {
698
 
        logMessage("PulseAudio support disabled: PHONON_PULSEAUDIO_DISABLE is set");
 
711
        logMessage(QLatin1String("PulseAudio support disabled: PHONON_PULSEAUDIO_DISABLE is set"));
699
712
        return;
700
713
    }
701
714
 
702
715
    // We require a glib event loop
703
 
    if (QLatin1String(QAbstractEventDispatcher::instance()->metaObject()->className())
704
 
            != "QGuiEventDispatcherGlib") {
705
 
        logMessage("Disabling PulseAudio integration for lack of GLib event loop.");
 
716
    if (strcmp(QAbstractEventDispatcher::instance()->metaObject()->className(),
 
717
               "QGuiEventDispatcherGlib") != 0) {
 
718
        qWarning("WARNING: Disabling PulseAudio integration for lack of GLib event loop.");
706
719
        return;
707
720
    }
708
721
 
710
723
    // use a fully async integrated mainloop method to connect and get proper support.
711
724
    pa_mainloop *p_test_mainloop;
712
725
    if (!(p_test_mainloop = pa_mainloop_new())) {
713
 
        logMessage("PulseAudio support disabled: Unable to create mainloop");
 
726
        logMessage(QLatin1String("PulseAudio support disabled: Unable to create mainloop"));
714
727
        return;
715
728
    }
716
729
 
717
730
    pa_context *p_test_context;
718
731
    if (!(p_test_context = pa_context_new(pa_mainloop_get_api(p_test_mainloop), "libphonon-probe"))) {
719
 
        logMessage("PulseAudio support disabled: Unable to create context");
 
732
        logMessage(QLatin1String("PulseAudio support disabled: Unable to create context"));
720
733
        pa_mainloop_free(p_test_mainloop);
721
734
        return;
722
735
    }
723
736
 
724
 
    logMessage("Probing for PulseAudio...");
 
737
    logMessage(QLatin1String("Probing for PulseAudio..."));
725
738
    // (cg) Convert to PA_CONTEXT_NOFLAGS when PulseAudio 0.9.19 is required
726
739
    if (pa_context_connect(p_test_context, NULL, static_cast<pa_context_flags_t>(0), NULL) < 0) {
727
 
        logMessage(QString("PulseAudio support disabled: %1").arg(pa_strerror(pa_context_errno(p_test_context))));
 
740
        logMessage(QString::fromLatin1("PulseAudio support disabled: %1").arg(QString::fromLocal8Bit(pa_strerror(pa_context_errno(p_test_context)))));
728
741
        pa_context_disconnect(p_test_context);
729
742
        pa_context_unref(p_test_context);
730
743
        pa_mainloop_free(p_test_mainloop);
736
749
        pa_mainloop_iterate(p_test_mainloop, 1, NULL);
737
750
 
738
751
        if (!PA_CONTEXT_IS_GOOD(pa_context_get_state(p_test_context))) {
739
 
            logMessage("PulseAudio probe complete.");
 
752
            logMessage(QLatin1String("PulseAudio probe complete."));
740
753
            break;
741
754
        }
742
755
    }
745
758
    pa_mainloop_free(p_test_mainloop);
746
759
 
747
760
    if (!s_pulseActive) {
748
 
        logMessage("PulseAudio support is not available.");
 
761
        logMessage(QLatin1String("PulseAudio support is not available."));
749
762
        return;
750
763
    }
751
764
 
752
765
    // If we're still here, PA is available.
753
 
    logMessage("PulseAudio support enabled");
 
766
    logMessage(QLatin1String("PulseAudio support enabled"));
754
767
 
755
768
    // Now we connect for real using a proper main loop that we can forget
756
769
    // all about processing.
801
814
{
802
815
    mEnabled = enabled;
803
816
#ifdef HAVE_PULSEAUDIO
804
 
    logMessage(QString("Enabled Breakdown: mEnabled: %1, s_pulseActive %2").arg(mEnabled ? "Yes" : "No" ).arg(s_pulseActive ? "Yes" : "No"));
 
817
    logMessage(QString::fromLocal8Bit("Enabled Breakdown: mEnabled: %1, s_pulseActive %2").arg(mEnabled ? "Yes" : "No" ).arg(s_pulseActive ? "Yes" : "No"));
805
818
#endif
806
819
}
807
820
 
910
923
    if (role.isEmpty())
911
924
        return;
912
925
 
913
 
    logMessage(QString("Reindexing %1: %2").arg(role).arg(list.join(", ")));
 
926
    logMessage(QString::fromLatin1("Reindexing %1: %2").arg(role).arg(list.join(QLatin1String(", "))));
914
927
 
915
928
    char **devices;
916
929
    devices = pa_xnew(char *, list.size()+1);
917
930
    int i = 0;
918
 
    foreach (QString str, list) {
 
931
    foreach (const QString &str, list) {
919
932
        devices[i++] = pa_xstrdup(str.toUtf8().constData());
920
933
    }
921
934
    devices[list.size()] = NULL;
922
935
 
923
 
#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER 
 
936
#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER
924
937
    pa_operation *o;
925
938
    if (!(o = pa_ext_device_manager_reorder_devices_for_role(s_context, role.toUtf8().constData(), (const char**)devices, NULL, NULL)))
926
 
        logMessage(QString("pa_ext_device_manager_reorder_devices_for_role() failed"));
 
939
        logMessage(QString::fromLatin1("pa_ext_device_manager_reorder_devices_for_role() failed"));
927
940
    else
928
941
        pa_operation_unref(o);
929
942
#endif
973
986
#ifdef HAVE_PULSEAUDIO
974
987
static PulseStream* register_stream(QMap<QString,PulseStream*> &map, QString streamUuid, Category category)
975
988
{
976
 
    logMessage(QString("Initialising streamindex %1").arg(streamUuid));
 
989
    logMessage(QString::fromLatin1("Initialising streamindex %1").arg(streamUuid));
977
990
    QString role = s_roleCategoryMap.key(category);
978
991
    if (!role.isEmpty()) {
979
 
        logMessage(QString("Setting role to %1 for streamindex %2").arg(role).arg(streamUuid));
 
992
        logMessage(QString::fromLatin1("Setting role to %1 for streamindex %2").arg(role).arg(streamUuid));
980
993
        setenv("PULSE_PROP_media.role", role.toLatin1().constData(), 1);
981
994
    }
982
995
    setenv("PULSE_PROP_phonon.streamid", streamUuid.toLatin1().constData(), 1);
1020
1033
    Q_UNUSED(name);
1021
1034
    return false;
1022
1035
#else
1023
 
    logMessage(QString("Unimplemented: Need to find a way to set either application.name or media.name in SI proplist"));
 
1036
    logMessage(QString::fromLatin1("Unimplemented: Need to find a way to set either application.name or media.name in SI proplist"));
1024
1037
    Q_UNUSED(streamUuid);
1025
1038
    Q_UNUSED(name);
1026
1039
    return true;
1037
1050
        return true;
1038
1051
 
1039
1052
    if (!s_outputDevices.contains(device)) {
1040
 
        logMessage(QString("Attempting to set Output Device for invalid device id %1.").arg(device));
 
1053
        logMessage(QString::fromLatin1("Attempting to set Output Device for invalid device id %1.").arg(device));
1041
1054
        return false;
1042
1055
    }
1043
1056
    const QVariant var = s_outputDevices[device].properties["name"];
1044
 
    logMessage(QString("Attempting to set Output Device to '%1' for Output Stream %2").arg(var.toString()).arg(streamUuid));
 
1057
    logMessage(QString::fromLatin1("Attempting to set Output Device to '%1' for Output Stream %2").arg(var.toString()).arg(streamUuid));
1045
1058
 
1046
1059
    // Attempt to look up the pulse stream index.
1047
1060
    if (s_outputStreams.contains(streamUuid) && s_outputStreams[streamUuid]->index() != PA_INVALID_INDEX) {
1048
 
        logMessage(QString("... Found in map. Moving now"));
 
1061
        logMessage(QString::fromLatin1("... Found in map. Moving now"));
1049
1062
 
1050
1063
        uint32_t pulse_device_index = s_outputDevices[device].pulseIndex;
1051
1064
        uint32_t pulse_stream_index = s_outputStreams[streamUuid]->index();
1052
1065
 
1053
 
        logMessage(QString("Moving Pulse Sink Input %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index));
 
1066
        logMessage(QString::fromLatin1("Moving Pulse Sink Input %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index));
1054
1067
 
1055
1068
        /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db.
1056
1069
        pa_operation* o;
1057
1070
        if (!(o = pa_context_move_sink_input_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) {
1058
 
            logMessage(QString("pa_context_move_sink_input_by_index() failed"));
 
1071
            logMessage(QString::fromLatin1("pa_context_move_sink_input_by_index() failed"));
1059
1072
            return false;
1060
1073
        }
1061
1074
        pa_operation_unref(o);
1062
1075
    } else {
1063
 
        logMessage(QString("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then"));
 
1076
        logMessage(QString::fromLatin1("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then"));
1064
1077
    }
1065
1078
    return true;
1066
1079
#endif
1072
1085
    Q_UNUSED(volume);
1073
1086
    return false;
1074
1087
#else
1075
 
    logMessage(QString("Attempting to set volume to %1 for Output Stream %2").arg(volume).arg(streamUuid));
 
1088
    logMessage(QString::fromLatin1("Attempting to set volume to %1 for Output Stream %2").arg(volume).arg(streamUuid));
1076
1089
 
1077
1090
    // Attempt to look up the pulse stream index.
1078
1091
    if (s_outputStreams.contains(streamUuid) && s_outputStreams[streamUuid]->index() != PA_INVALID_INDEX) {
1080
1093
 
1081
1094
        uint8_t channels = stream->channels();
1082
1095
        if (channels < 1) {
1083
 
            logMessage("Channel count is less than 1. Cannot set volume.");
 
1096
            logMessage(QString::fromLatin1("Channel count is less than 1. Cannot set volume."));
1084
1097
            return false;
1085
1098
        }
1086
1099
 
1087
1100
        pa_cvolume vol;
1088
1101
        pa_cvolume_set(&vol, channels, (volume * PA_VOLUME_NORM));
1089
1102
 
1090
 
        logMessage(QString("Found PA index %1. Calling pa_context_set_sink_input_volume()").arg(stream->index()));
 
1103
        logMessage(QString::fromLatin1("Found PA index %1. Calling pa_context_set_sink_input_volume()").arg(stream->index()));
1091
1104
        pa_operation* o;
1092
1105
        if (!(o = pa_context_set_sink_input_volume(s_context, stream->index(), &vol, NULL, NULL))) {
1093
 
            logMessage(QString("pa_context_set_sink_input_volume() failed"));
 
1106
            logMessage(QString::fromLatin1("pa_context_set_sink_input_volume() failed"));
1094
1107
            return false;
1095
1108
        }
1096
1109
        pa_operation_unref(o);
1105
1118
    Q_UNUSED(mute);
1106
1119
    return false;
1107
1120
#else
1108
 
    logMessage(QString("Attempting to %1 mute for Output Stream %2").arg(mute ? "set" : "unset").arg(streamUuid));
 
1121
    logMessage(QString::fromLatin1("Attempting to %1 mute for Output Stream %2").arg(mute ? "set" : "unset").arg(streamUuid));
1109
1122
 
1110
1123
    // Attempt to look up the pulse stream index.
1111
1124
    if (s_outputStreams.contains(streamUuid) && s_outputStreams[streamUuid]->index() != PA_INVALID_INDEX) {
1112
1125
        PulseStream *stream = s_outputStreams[streamUuid];
1113
1126
 
1114
 
        logMessage(QString("Found PA index %1. Calling pa_context_set_sink_input_mute()").arg(stream->index()));
 
1127
        logMessage(QString::fromLatin1("Found PA index %1. Calling pa_context_set_sink_input_mute()").arg(stream->index()));
1115
1128
        pa_operation* o;
1116
1129
        if (!(o = pa_context_set_sink_input_mute(s_context, stream->index(), (mute ? 1 : 0), NULL, NULL))) {
1117
 
            logMessage(QString("pa_context_set_sink_input_mute() failed"));
 
1130
            logMessage(QString::fromLatin1("pa_context_set_sink_input_mute() failed"));
1118
1131
            return false;
1119
1132
        }
1120
1133
        pa_operation_unref(o);
1133
1146
        return true;
1134
1147
 
1135
1148
    if (!s_captureDevices.contains(device)) {
1136
 
        logMessage(QString("Attempting to set Capture Device for invalid device id %1.").arg(device));
 
1149
        logMessage(QString::fromLatin1("Attempting to set Capture Device for invalid device id %1.").arg(device));
1137
1150
        return false;
1138
1151
    }
1139
1152
    const QVariant var = s_captureDevices[device].properties["name"];
1140
 
    logMessage(QString("Attempting to set Capture Device to '%1' for Capture Stream %2").arg(var.toString()).arg(streamUuid));
 
1153
    logMessage(QString::fromLatin1("Attempting to set Capture Device to '%1' for Capture Stream %2").arg(var.toString()).arg(streamUuid));
1141
1154
 
1142
1155
    // Attempt to look up the pulse stream index.
1143
1156
    if (s_captureStreams.contains(streamUuid) && s_captureStreams[streamUuid]->index() == PA_INVALID_INDEX) {
1144
 
        logMessage(QString("... Found in map. Moving now"));
 
1157
        logMessage(QString::fromLatin1("... Found in map. Moving now"));
1145
1158
 
1146
1159
        uint32_t pulse_device_index = s_captureDevices[device].pulseIndex;
1147
1160
        uint32_t pulse_stream_index = s_captureStreams[streamUuid]->index();
1148
1161
 
1149
 
        logMessage(QString("Moving Pulse Source Output %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index));
 
1162
        logMessage(QString::fromLatin1("Moving Pulse Source Output %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index));
1150
1163
 
1151
1164
        /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db.
1152
1165
        pa_operation* o;
1153
1166
        if (!(o = pa_context_move_source_output_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) {
1154
 
            logMessage(QString("pa_context_move_source_output_by_index() failed"));
 
1167
            logMessage(QString::fromLatin1("pa_context_move_source_output_by_index() failed"));
1155
1168
            return false;
1156
1169
        }
1157
1170
        pa_operation_unref(o);
1158
1171
    } else {
1159
 
        logMessage(QString("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then"));
 
1172
        logMessage(QString::fromLatin1("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then"));
1160
1173
    }
1161
1174
    return true;
1162
1175
#endif
1167
1180
    Q_UNUSED(streamUuid);
1168
1181
    return;
1169
1182
#else
1170
 
    logMessage(QString("Clearing stream cache for stream %1").arg(streamUuid));
 
1183
    logMessage(QString::fromLatin1("Clearing stream cache for stream %1").arg(streamUuid));
1171
1184
    if (s_outputStreams.contains(streamUuid)) {
1172
1185
        PulseStream *stream = s_outputStreams[streamUuid];
1173
1186
        s_outputStreams.remove(streamUuid);