]> git.seodisparate.com - MeterForPulseAudio/commitdiff
Add feature list available sinks/sources 1.3
authorStephen Seo <seo.disparate@gmail.com>
Tue, 19 Jun 2018 05:13:01 +0000 (14:13 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Tue, 19 Jun 2018 05:13:01 +0000 (14:13 +0900)
CMakeLists.txt
Changelog.md
src/Main.cpp
src/MfPA/GetSinkSourceInfo.cpp [new file with mode: 0644]
src/MfPA/GetSinkSourceInfo.hpp [new file with mode: 0644]
src/MfPA/Meter.cpp

index c9bb0060c3c3f48a2e58f5d4ccd84108b6eba097..9575e54d1b84181fd83c7ee695a5e9344feb78fc 100644 (file)
@@ -1,11 +1,12 @@
 cmake_minimum_required(VERSION 3.0)
 
-project(MeterForPulseAudio VERSION 1.2)
+project(MeterForPulseAudio VERSION 1.3)
 
 set(MeterForPulseAudio_SOURCES
     GameDevTools/src/GDT/GameLoop.cpp
     src/Main.cpp
     src/MfPA/Meter.cpp
+    src/MfPA/GetSinkSourceInfo.cpp
 )
 
 # check if submodules are loaded
index 2195dfcd98538062df233390af98f6795cfa3fad..d99e78a8ab97ef097d05a10548c87be2543830d6 100644 (file)
@@ -1,3 +1,8 @@
+# Version 1.3
+
+Added feature to print available sinks/sources (invoked via arguments to
+program).
+
 # Version 1.2
 
 Improved error output when failed getting info on sink/source.
index 0073d1ab8c61bfc543600d62569510ddedc91a5e..4c45a2e7cbeeede1a628a6ea0209a83b21a1396b 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <ADP/AnotherDangParser.hpp>
 #include "MfPA/Meter.hpp"
+#include "MfPA/GetSinkSourceInfo.hpp"
 
 int main(int argc, char** argv)
 {
@@ -86,6 +87,20 @@ int main(int argc, char** argv)
         },
         "Sets the bar color to a specified color (hex input like 0xFFFFFF, "
         "red is most significant byte out of 3)");
+    parser.addLongFlag("list-sinks",
+        [] () {
+            MfPA::GetSinkSourceInfo getInfo(true);
+            getInfo.startMainLoop();
+            std::exit(0);
+        },
+        "Lists available PulseAudio sinks");
+    parser.addLongFlag("list-sources",
+        [] () {
+            MfPA::GetSinkSourceInfo getInfo(false);
+            getInfo.startMainLoop();
+            std::exit(0);
+        },
+        "Lists available PulseAudio sources");
     parser.addFlag(
         "h",
         [&parser] () {
diff --git a/src/MfPA/GetSinkSourceInfo.cpp b/src/MfPA/GetSinkSourceInfo.cpp
new file mode 100644 (file)
index 0000000..3aa9fc0
--- /dev/null
@@ -0,0 +1,121 @@
+#include "GetSinkSourceInfo.hpp"
+
+#include <iostream>
+
+#include <GDT/GameLoop.hpp>
+
+MfPA::GetSinkSourceInfo::GetSinkSourceInfo(bool getSinkInfo) :
+getSinkInfo(getSinkInfo),
+isReady(false),
+run(true)
+{
+    mainLoop = pa_mainloop_new();
+    context = pa_context_new(
+        pa_mainloop_get_api(mainLoop), "Get Pulse Sink/Source Info");
+    pa_context_set_state_callback(
+        context,
+        MfPA::GetSinkSourceInfo::get_state_callback,
+        this);
+    pa_context_connect(context, nullptr, PA_CONTEXT_NOFLAGS, nullptr);
+}
+
+MfPA::GetSinkSourceInfo::~GetSinkSourceInfo()
+{
+    if(context)
+    {
+        pa_context_disconnect(context);
+        pa_context_unref(context);
+    }
+
+    if(mainLoop)
+    {
+        pa_mainloop_free(mainLoop);
+    }
+}
+
+void MfPA::GetSinkSourceInfo::get_state_callback(pa_context* c, void* userdata)
+{
+    MfPA::GetSinkSourceInfo* getInfo = (MfPA::GetSinkSourceInfo*) userdata;
+    switch(pa_context_get_state(c))
+    {
+    case PA_CONTEXT_UNCONNECTED:
+    case PA_CONTEXT_CONNECTING:
+    case PA_CONTEXT_AUTHORIZING:
+    case PA_CONTEXT_SETTING_NAME:
+        break;
+    case PA_CONTEXT_READY:
+        getInfo->isReady = true;
+        if(getInfo->getSinkInfo)
+        {
+            std::cout << "Available sinks:" << std::endl;
+            pa_operation_unref(pa_context_get_sink_info_list(
+                c,
+                MfPA::GetSinkSourceInfo::get_sink_info_callback,
+                userdata));
+        }
+        else
+        {
+            std::cout << "Available sources:" << std::endl;
+            pa_operation_unref(pa_context_get_source_info_list(
+                c,
+                MfPA::GetSinkSourceInfo::get_source_info_callback,
+                userdata));
+        }
+        break;
+    case PA_CONTEXT_FAILED:
+        std::cerr << "ERROR during context state callback: "
+            << pa_strerror(pa_context_errno(c)) << std::endl;
+    case PA_CONTEXT_TERMINATED:
+        getInfo->run = false;
+        break;
+    }
+}
+
+void MfPA::GetSinkSourceInfo::get_sink_info_callback(
+    pa_context* c,
+    const pa_sink_info* i,
+    int eol,
+    void* userdata)
+{
+//    MfPA::GetSinkSourceInfo* getInfo = (MfPA::GetSinkSourceInfo*) userdata;
+    if(eol != PA_OK)
+    {
+        return;
+    }
+    std::cout << "  " << i->name << std::endl;
+}
+
+void MfPA::GetSinkSourceInfo::get_source_info_callback(
+    pa_context* c,
+    const pa_source_info* i,
+    int eol,
+    void* userdata)
+{
+//    MfPA::GetSinkSourceInfo* getInfo = (MfPA::GetSinkSourceInfo*) userdata;
+    if(eol != PA_OK)
+    {
+        return;
+    }
+    std::cout << "  " << i->name << std::endl;
+}
+
+void MfPA::GetSinkSourceInfo::startMainLoop()
+{
+    float timer = GET_SINK_SOURCE_INFO_ITERATION_TIME;
+    GDT::IntervalBasedGameLoop(
+        &run,
+        [this, &timer] (float dt) {
+            pa_mainloop_iterate(mainLoop, 0, nullptr);
+            if(isReady)
+            {
+                timer -= dt;
+                if(timer <= 0.0f)
+                {
+                    run = false;
+                }
+            }
+        },
+        [] () {},
+        60,
+        1.0f / 120.0f);
+}
diff --git a/src/MfPA/GetSinkSourceInfo.hpp b/src/MfPA/GetSinkSourceInfo.hpp
new file mode 100644 (file)
index 0000000..b9110df
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef GET_SINK_SOURCE_INFO_HPP
+#define GET_SINK_SOURCE_INFO_HPP
+
+#define GET_SINK_SOURCE_INFO_ITERATION_TIME 1.0f
+
+#include <pulse/pulseaudio.h>
+
+namespace MfPA
+{
+
+class GetSinkSourceInfo
+{
+public:
+    GetSinkSourceInfo(bool getSinkInfo);
+    ~GetSinkSourceInfo();
+
+    static void get_state_callback(pa_context* c, void* userdata);
+    static void get_sink_info_callback(
+        pa_context* c,
+        const pa_sink_info* i,
+        int eol,
+        void* userdata);
+    static void get_source_info_callback(
+        pa_context* c,
+        const pa_source_info* i,
+        int eol,
+        void* userdata);
+
+    void startMainLoop();
+
+private:
+    bool getSinkInfo;
+
+    pa_mainloop* mainLoop;
+    pa_context* context;
+    bool isReady;
+
+    bool run;
+
+};
+
+} // namespace MfPA
+
+#endif
index b907b418eebc855bceef56b20279761940461f2a..7933942923dc383358389bf5a159e554c09fd986 100644 (file)
@@ -34,7 +34,8 @@ barColor(barColor)
     setenv("PULSE_PROP_application.icon_name", "multimedia-volume-control", 1);
 
     mainLoop = pa_mainloop_new();
-    context = pa_context_new(pa_mainloop_get_api(mainLoop), "Meter for PulseAudio");
+    context = pa_context_new(
+        pa_mainloop_get_api(mainLoop), "Meter for PulseAudio");
     pa_context_set_state_callback(
         context,
         MfPA::Meter::get_context_callback,