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);
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);
97
99
: pulseName(name), pulseIndex(index)
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!
107
DeviceAccessList dal;
108
dal.append(DeviceAccess("pulse", desc));
109
properties["deviceAccessList"] = QVariant::fromValue<DeviceAccessList>(dal);
106
112
// Needed for QMap
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);
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
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."));
420
426
// loop through (*i) and extract phonon->streamindex...
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)));
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);
463
469
// loop through (*i) and extract phonon->streamindex...
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)));
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);
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);
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"));
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);
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);
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"));
523
529
pa_operation_unref(o);
530
static const char* statename(pa_context_state_t state)
536
static QString statename(pa_context_state_t state)
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");
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);
548
552
static void context_state_callback(pa_context *c, void *)
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"));
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);
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"));
585
589
pa_operation_unref(o);
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);
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"));
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"));
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()
655
659
if (NULL == s_instance) {
656
s_instance = new PulseSupport();
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.
667
if (NULL == s_instance)
668
s_instance = new PulseSupport();
658
671
return s_instance;
669
682
void PulseSupport::debug()
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"));
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;
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"));
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.");
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"));
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);
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);
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."));
745
758
pa_mainloop_free(p_test_mainloop);
747
760
if (!s_pulseActive) {
748
logMessage("PulseAudio support is not available.");
761
logMessage(QLatin1String("PulseAudio support is not available."));
752
765
// If we're still here, PA is available.
753
logMessage("PulseAudio support enabled");
766
logMessage(QLatin1String("PulseAudio support enabled"));
755
768
// Now we connect for real using a proper main loop that we can forget
756
769
// all about processing.
910
923
if (role.isEmpty())
913
logMessage(QString("Reindexing %1: %2").arg(role).arg(list.join(", ")));
926
logMessage(QString::fromLatin1("Reindexing %1: %2").arg(role).arg(list.join(QLatin1String(", "))));
916
929
devices = pa_xnew(char *, list.size()+1);
918
foreach (QString str, list) {
931
foreach (const QString &str, list) {
919
932
devices[i++] = pa_xstrdup(str.toUtf8().constData());
921
934
devices[list.size()] = NULL;
923
#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER
936
#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER
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"));
928
941
pa_operation_unref(o);
973
986
#ifdef HAVE_PULSEAUDIO
974
987
static PulseStream* register_stream(QMap<QString,PulseStream*> &map, QString streamUuid, Category category)
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);
982
995
setenv("PULSE_PROP_phonon.streamid", streamUuid.toLatin1().constData(), 1);
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));
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));
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"));
1050
1063
uint32_t pulse_device_index = s_outputDevices[device].pulseIndex;
1051
1064
uint32_t pulse_stream_index = s_outputStreams[streamUuid]->index();
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));
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"));
1061
1074
pa_operation_unref(o);
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"));
1072
1085
Q_UNUSED(volume);
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));
1077
1090
// Attempt to look up the pulse stream index.
1078
1091
if (s_outputStreams.contains(streamUuid) && s_outputStreams[streamUuid]->index() != PA_INVALID_INDEX) {
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."));
1087
1100
pa_cvolume vol;
1088
1101
pa_cvolume_set(&vol, channels, (volume * PA_VOLUME_NORM));
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"));
1096
1109
pa_operation_unref(o);
1105
1118
Q_UNUSED(mute);
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));
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];
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"));
1120
1133
pa_operation_unref(o);
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));
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));
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"));
1146
1159
uint32_t pulse_device_index = s_captureDevices[device].pulseIndex;
1147
1160
uint32_t pulse_stream_index = s_captureStreams[streamUuid]->index();
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));
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"));
1157
1170
pa_operation_unref(o);
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"));
1167
1180
Q_UNUSED(streamUuid);
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);