<commit_before>#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "e_mod_system.h"
#include "e_mod_main.h"
#include <Ecore.h>
#include "Pulse.h"

//#define BAD_CH_MAPPING 1

#define PULSE_BUS "org.PulseAudio.Core1"
#define PULSE_PATH "/org/pulseaudio/core1"
#define PULSE_INTERFACE "org.PulseAudio.Core1"

static Pulse *conn = NULL;
static Ecore_Event_Handler *ph = NULL;
static Ecore_Event_Handler *pch = NULL;
static Ecore_Event_Handler *pdh = NULL;
static Eina_List *sinks = NULL;
static Eina_List *sources = NULL;

static E_DBus_Connection *dbus = NULL;
static E_DBus_Signal_Handler *dbus_handler = NULL;
static double last_disc = 0;

static void
_dbus_poll(void *data   __UNUSED__,
           DBusMessage *msg)
{
   DBusError err;
   const char *name, *from, *to;

   dbus_error_init(&err);
   if (!dbus_message_get_args(msg, &err,
                              DBUS_TYPE_STRING, &name,
                              DBUS_TYPE_STRING, &from,
                              DBUS_TYPE_STRING, &to,
                              DBUS_TYPE_INVALID))
     dbus_error_free(&err);

   //printf("name: %s\nfrom: %s\nto: %s\n", name, from, to);
   if ((name) && !strcmp(name, PULSE_BUS))
     e_mixer_pulse_init();
   if (dbus_handler)
     {
        e_dbus_signal_handler_del(dbus, dbus_handler);
        dbus_handler = NULL;
     }
   if (dbus)
     {
        e_dbus_connection_close(dbus);
        dbus = NULL;
        e_dbus_shutdown();
     }
}

static void
_dbus_test(void *data       __UNUSED__,
           DBusMessage *msg __UNUSED__,
           DBusError       *error)
{
   if ((error) && (dbus_error_is_set(error)))
     {
        dbus_error_free(error);
        if (dbus_handler)
          {
             e_dbus_signal_handler_del(dbus, dbus_handler);
             dbus_handler = NULL;
          }
        if (dbus)
          {
             e_dbus_connection_close(dbus);
             dbus = NULL;
             e_dbus_shutdown();
          }
        e_mod_mixer_pulse_ready(EINA_FALSE);
        return;
     }
}

static Eina_Bool
_pulse_update(Pulse *d __UNUSED__, int type __UNUSED__, Pulse_Sink *ev __UNUSED__)
{
   e_mod_mixer_pulse_update();
   return EINA_TRUE;
}

static void
_pulse_sinks_get(Pulse *p __UNUSED__, Pulse_Tag_Id id __UNUSED__, Eina_List *ev)
{
   Eina_List *l;
   Pulse_Sink *sink;
   sinks = ev;
   EINA_LIST_FOREACH(ev, l, sink)
     {
        printf("Sink:\n");
        printf("\tname: %s\n", pulse_sink_name_get(sink));
        printf("\tidx: %"PRIu32"\n", pulse_sink_idx_get(sink));
        printf("\tdesc: %s\n", pulse_sink_desc_get(sink));
        printf("\tchannels: %u\n", pulse_sink_channels_count(sink));
        printf("\tmuted: %s\n", pulse_sink_muted_get(sink) ? "yes" : "no");
        printf("\tavg: %g\n", pulse_sink_avg_get_pct(sink));
        printf("\tbalance: %f\n", pulse_sink_balance_get(sink));
     }
   pulse_sinks_watch(conn);
   e_mod_mixer_pulse_ready(EINA_TRUE);
}

static void
_pulse_sources_get(Pulse *p __UNUSED__, Pulse_Tag_Id id __UNUSED__, Eina_List *ev)
{
   Eina_List *l;
   Pulse_Sink *sink;
   sources = ev;
   EINA_LIST_FOREACH(ev, l, sink)
     {
        printf("Sources:\n");
        printf("\tname: %s\n", pulse_sink_name_get(sink));
        printf("\tidx: %"PRIu32"\n", pulse_sink_idx_get(sink));
        printf("\tdesc: %s\n", pulse_sink_desc_get(sink));
        printf("\tchannels: %u\n", pulse_sink_channels_count(sink));
        printf("\tmuted: %s\n", pulse_sink_muted_get(sink) ? "yes" : "no");
        printf("\tavg: %g\n", pulse_sink_avg_get_pct(sink));
        printf("\tbalance: %f\n", pulse_sink_balance_get(sink));
     }
}

static Eina_Bool
_pulse_connected(Pulse *d, int type __UNUSED__, Pulse *ev)
{
   Pulse_Tag_Id id;
   if (d != ev) return ECORE_CALLBACK_PASS_ON;
   id = pulse_sinks_get(conn);
   if (!id)
     {
        e_mixer_pulse_shutdown();
        e_mixer_default_setup();
        return ECORE_CALLBACK_RENEW;
     }
   pulse_cb_set(conn, id, (Pulse_Cb)_pulse_sinks_get);
   id = pulse_sources_get(conn);
   if (id)
     pulse_cb_set(conn, id, (Pulse_Cb)_pulse_sources_get);
   return ECORE_CALLBACK_RENEW;
}

static Eina_Bool
_pulse_disconnected(Pulse *d, int type __UNUSED__, Pulse *ev)
{
   Pulse_Sink *sink;

   if (d != ev) return ECORE_CALLBACK_PASS_ON;

   EINA_LIST_FREE(sinks, sink)
     pulse_sink_free(sink);
   EINA_LIST_FREE(sources, sink)
     pulse_sink_free(sink);

   printf("PULSEAUDIO: disconnected at %g\n", ecore_time_unix_get());

   if (last_disc && (ecore_time_unix_get() - last_disc < 1))
     {
        e_mixer_pulse_shutdown();
        last_disc = 0;
        e_mod_mixer_pulse_ready(EINA_FALSE);
     }
   else
     {
        pulse_connect(conn);
        last_disc = ecore_time_unix_get();
     }
   return ECORE_CALLBACK_RENEW;
}

static Pulse_Sink *
_pulse_sink_find(const char *name)
{
   Eina_List *l;
   Pulse_Sink *sink;<commit_msg>add debug message for throttling<commit_after>#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "e_mod_system.h"
#include "e_mod_main.h"
#include <Ecore.h>
#include "Pulse.h"

//#define BAD_CH_MAPPING 1

#define PULSE_BUS "org.PulseAudio.Core1"
#define PULSE_PATH "/org/pulseaudio/core1"
#define PULSE_INTERFACE "org.PulseAudio.Core1"

static Pulse *conn = NULL;
static Ecore_Event_Handler *ph = NULL;
static Ecore_Event_Handler *pch = NULL;
static Ecore_Event_Handler *pdh = NULL;
static Eina_List *sinks = NULL;
static Eina_List *sources = NULL;

static E_DBus_Connection *dbus = NULL;
static E_DBus_Signal_Handler *dbus_handler = NULL;
static double last_disc = 0;

static void
_dbus_poll(void *data   __UNUSED__,
           DBusMessage *msg)
{
   DBusError err;
   const char *name, *from, *to;

   dbus_error_init(&err);
   if (!dbus_message_get_args(msg, &err,
                              DBUS_TYPE_STRING, &name,
                              DBUS_TYPE_STRING, &from,
                              DBUS_TYPE_STRING, &to,
                              DBUS_TYPE_INVALID))
     dbus_error_free(&err);

   //printf("name: %s\nfrom: %s\nto: %s\n", name, from, to);
   if ((name) && !strcmp(name, PULSE_BUS))
     e_mixer_pulse_init();
   if (dbus_handler)
     {
        e_dbus_signal_handler_del(dbus, dbus_handler);
        dbus_handler = NULL;
     }
   if (dbus)
     {
        e_dbus_connection_close(dbus);
        dbus = NULL;
        e_dbus_shutdown();
     }
}

static void
_dbus_test(void *data       __UNUSED__,
           DBusMessage *msg __UNUSED__,
           DBusError       *error)
{
   if ((error) && (dbus_error_is_set(error)))
     {
        dbus_error_free(error);
        if (dbus_handler)
          {
             e_dbus_signal_handler_del(dbus, dbus_handler);
             dbus_handler = NULL;
          }
        if (dbus)
          {
             e_dbus_connection_close(dbus);
             dbus = NULL;
             e_dbus_shutdown();
          }
        e_mod_mixer_pulse_ready(EINA_FALSE);
        return;
     }
}

static Eina_Bool
_pulse_update(Pulse *d __UNUSED__, int type __UNUSED__, Pulse_Sink *ev __UNUSED__)
{
   e_mod_mixer_pulse_update();
   return EINA_TRUE;
}

static void
_pulse_sinks_get(Pulse *p __UNUSED__, Pulse_Tag_Id id __UNUSED__, Eina_List *ev)
{
   Eina_List *l;
   Pulse_Sink *sink;
   sinks = ev;
   EINA_LIST_FOREACH(ev, l, sink)
     {
        printf("Sink:\n");
        printf("\tname: %s\n", pulse_sink_name_get(sink));
        printf("\tidx: %"PRIu32"\n", pulse_sink_idx_get(sink));
        printf("\tdesc: %s\n", pulse_sink_desc_get(sink));
        printf("\tchannels: %u\n", pulse_sink_channels_count(sink));
        printf("\tmuted: %s\n", pulse_sink_muted_get(sink) ? "yes" : "no");
        printf("\tavg: %g\n", pulse_sink_avg_get_pct(sink));
        printf("\tbalance: %f\n", pulse_sink_balance_get(sink));
     }
   pulse_sinks_watch(conn);
   e_mod_mixer_pulse_ready(EINA_TRUE);
}

static void
_pulse_sources_get(Pulse *p __UNUSED__, Pulse_Tag_Id id __UNUSED__, Eina_List *ev)
{
   Eina_List *l;
   Pulse_Sink *sink;
   sources = ev;
   EINA_LIST_FOREACH(ev, l, sink)
     {
        printf("Sources:\n");
        printf("\tname: %s\n", pulse_sink_name_get(sink));
        printf("\tidx: %"PRIu32"\n", pulse_sink_idx_get(sink));
        printf("\tdesc: %s\n", pulse_sink_desc_get(sink));
        printf("\tchannels: %u\n", pulse_sink_channels_count(sink));
        printf("\tmuted: %s\n", pulse_sink_muted_get(sink) ? "yes" : "no");
        printf("\tavg: %g\n", pulse_sink_avg_get_pct(sink));
        printf("\tbalance: %f\n", pulse_sink_balance_get(sink));
     }
}

static Eina_Bool
_pulse_connected(Pulse *d, int type __UNUSED__, Pulse *ev)
{
   Pulse_Tag_Id id;
   if (d != ev) return ECORE_CALLBACK_PASS_ON;
   id = pulse_sinks_get(conn);
   if (!id)
     {
        e_mixer_pulse_shutdown();
        e_mixer_default_setup();
        return ECORE_CALLBACK_RENEW;
     }
   pulse_cb_set(conn, id, (Pulse_Cb)_pulse_sinks_get);
   id = pulse_sources_get(conn);
   if (id)
     pulse_cb_set(conn, id, (Pulse_Cb)_pulse_sources_get);
   return ECORE_CALLBACK_RENEW;
}

static Eina_Bool
_pulse_disconnected(Pulse *d, int type __UNUSED__, Pulse *ev)
{
   Pulse_Sink *sink;

   if (d != ev) return ECORE_CALLBACK_PASS_ON;

   EINA_LIST_FREE(sinks, sink)
     pulse_sink_free(sink);
   EINA_LIST_FREE(sources, sink)
     pulse_sink_free(sink);

   printf("PULSEAUDIO: disconnected at %g\n", ecore_time_unix_get());

   if (last_disc && (ecore_time_unix_get() - last_disc < 1))
     {
        fprintf(stderr, "PULSEAUDIO: disconnecting too quickly, THROTTLED\n");
        e_mixer_pulse_shutdown();
        last_disc = 0;
        e_mod_mixer_pulse_ready(EINA_FALSE);
     }
   else
     {
        pulse_connect(conn);
        last_disc = ecore_time_unix_get();
     }
   return ECORE_CALLBACK_RENEW;
}

static Pulse_Sink *
_pulse_sink_find(const char *name)
{
   Eina_List *l;
   Pulse_Sink *sink;
{'fraction_non_alphanumeric': 0.12230581537210249, 'fraction_numerical': 0.0022366815778771857, 'mean_word_length': 2.969733656174334, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '944887', 'n_tokens_mistral': 3853, 'n_tokens_neox': 3827, 'n_words': 665}