Hello community,

here is the log from the commit of package apulse for openSUSE:Factory checked 
in at 2015-12-29 12:59:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/apulse (Old)
 and      /work/SRC/openSUSE:Factory/.apulse.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "apulse"

Changes:
--------
--- /work/SRC/openSUSE:Factory/apulse/apulse.changes    2015-10-14 
16:44:37.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.apulse.new/apulse.changes       2015-12-29 
12:59:47.000000000 +0100
@@ -1,0 +2,8 @@
+Sat Dec 26 21:14:56 UTC 2015 - [email protected]
+
+- Update to 0.1.7:
+  * Make pa_proplist be able to store binary objects too.
+  * Implement pa_stream_begin_write.
+  * Bugfixes.
+
+-------------------------------------------------------------------

Old:
----
  apulse-0.1.6.tar.gz

New:
----
  apulse-0.1.7.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ apulse.spec ++++++
--- /var/tmp/diff_new_pack.h1w03M/_old  2015-12-29 12:59:48.000000000 +0100
+++ /var/tmp/diff_new_pack.h1w03M/_new  2015-12-29 12:59:48.000000000 +0100
@@ -18,7 +18,7 @@
 
 %define __provides_exclude_from ^%{_libdir}/apulse/.*.so.*$
 Name:           apulse
-Version:        0.1.6
+Version:        0.1.7
 Release:        0
 Summary:        PulseAudio emulation for ALSA
 License:        MIT

++++++ apulse-0.1.6.tar.gz -> apulse-0.1.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/apulse-channel-map.c 
new/apulse-0.1.7/src/apulse-channel-map.c
--- old/apulse-0.1.6/src/apulse-channel-map.c   2015-05-25 20:19:11.000000000 
+0200
+++ new/apulse-0.1.7/src/apulse-channel-map.c   2015-12-19 20:45:50.000000000 
+0100
@@ -25,6 +25,59 @@
 #include "apulse.h"
 #include "trace.h"
 
+static const char *channel_name[PA_CHANNEL_POSITION_MAX] = {
+    [PA_CHANNEL_POSITION_MONO] = "mono",
+    [PA_CHANNEL_POSITION_FRONT_CENTER] = "front-center",
+    [PA_CHANNEL_POSITION_FRONT_LEFT] = "front-left",
+    [PA_CHANNEL_POSITION_FRONT_RIGHT] = "front-right",
+    [PA_CHANNEL_POSITION_REAR_CENTER] = "rear-center",
+    [PA_CHANNEL_POSITION_REAR_LEFT] = "rear-left",
+    [PA_CHANNEL_POSITION_REAR_RIGHT] = "rear-right",
+    [PA_CHANNEL_POSITION_LFE] = "lfe",
+    [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "front-left-of-center",
+    [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "front-right-of-center",
+    [PA_CHANNEL_POSITION_SIDE_LEFT] = "side-left",
+    [PA_CHANNEL_POSITION_SIDE_RIGHT] = "side-right",
+    [PA_CHANNEL_POSITION_AUX0] = "aux0",
+    [PA_CHANNEL_POSITION_AUX1] = "aux1",
+    [PA_CHANNEL_POSITION_AUX2] = "aux2",
+    [PA_CHANNEL_POSITION_AUX3] = "aux3",
+    [PA_CHANNEL_POSITION_AUX4] = "aux4",
+    [PA_CHANNEL_POSITION_AUX5] = "aux5",
+    [PA_CHANNEL_POSITION_AUX6] = "aux6",
+    [PA_CHANNEL_POSITION_AUX7] = "aux7",
+    [PA_CHANNEL_POSITION_AUX8] = "aux8",
+    [PA_CHANNEL_POSITION_AUX9] = "aux9",
+    [PA_CHANNEL_POSITION_AUX10] = "aux10",
+    [PA_CHANNEL_POSITION_AUX11] = "aux11",
+    [PA_CHANNEL_POSITION_AUX12] = "aux12",
+    [PA_CHANNEL_POSITION_AUX13] = "aux13",
+    [PA_CHANNEL_POSITION_AUX14] = "aux14",
+    [PA_CHANNEL_POSITION_AUX15] = "aux15",
+    [PA_CHANNEL_POSITION_AUX16] = "aux16",
+    [PA_CHANNEL_POSITION_AUX17] = "aux17",
+    [PA_CHANNEL_POSITION_AUX18] = "aux18",
+    [PA_CHANNEL_POSITION_AUX19] = "aux19",
+    [PA_CHANNEL_POSITION_AUX20] = "aux20",
+    [PA_CHANNEL_POSITION_AUX21] = "aux21",
+    [PA_CHANNEL_POSITION_AUX22] = "aux22",
+    [PA_CHANNEL_POSITION_AUX23] = "aux23",
+    [PA_CHANNEL_POSITION_AUX24] = "aux24",
+    [PA_CHANNEL_POSITION_AUX25] = "aux25",
+    [PA_CHANNEL_POSITION_AUX26] = "aux26",
+    [PA_CHANNEL_POSITION_AUX27] = "aux27",
+    [PA_CHANNEL_POSITION_AUX28] = "aux28",
+    [PA_CHANNEL_POSITION_AUX29] = "aux29",
+    [PA_CHANNEL_POSITION_AUX30] = "aux30",
+    [PA_CHANNEL_POSITION_AUX31] = "aux31",
+    [PA_CHANNEL_POSITION_TOP_CENTER] = "top-center",
+    [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = "top-front-center",
+    [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = "top-front-left",
+    [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = "top-front-right",
+    [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = "top-rear-center",
+    [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = "top-rear-left",
+    [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = "top-rear-right",
+};
 
 APULSE_EXPORT
 pa_channel_map *
@@ -81,6 +134,83 @@
 }
 
 APULSE_EXPORT
+pa_channel_map *
+pa_channel_map_parse(pa_channel_map *map, const char *s)
+{
+    trace_info("F %s map=%p, s=%s\n", __func__, map, s);
+
+    pa_channel_map m = {};
+
+    if (strcmp(s, "stereo") == 0) {
+        m.channels = 2;
+        m.map[0] = PA_CHANNEL_POSITION_LEFT;
+        m.map[1] = PA_CHANNEL_POSITION_RIGHT;
+    } else if (strcmp(s, "surround-21") == 0) {
+        m.channels = 3;
+        m.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+        m.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+        m.map[2] = PA_CHANNEL_POSITION_LFE;
+    } else if (strcmp(s, "surround-40") == 0) {
+        m.channels = 4;
+        m.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+        m.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+        m.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
+        m.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
+    } else if (strcmp(s, "surround-41") == 0) {
+        m.channels = 5;
+        m.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+        m.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+        m.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
+        m.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
+        m.map[4] = PA_CHANNEL_POSITION_LFE;
+    } else if (strcmp(s, "surround-50") == 0) {
+        m.channels = 5;
+        m.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+        m.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+        m.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
+        m.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
+        m.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
+    } else if (strcmp(s, "surround-51") == 0) {
+        m.channels = 6;
+        m.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+        m.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+        m.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
+        m.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
+        m.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
+        m.map[5] = PA_CHANNEL_POSITION_LFE;
+    } else if (strcmp(s, "surround-51") == 0) {
+        m.channels = 8;
+        m.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+        m.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+        m.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
+        m.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
+        m.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
+        m.map[5] = PA_CHANNEL_POSITION_LFE;
+        m.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
+        m.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
+    }
+
+    if (m.channels > 0) {
+        // it was one of the predefined setups above
+        *map = m;
+        return map;
+    }
+
+    char **p = g_strsplit(s, ",", PA_CHANNELS_MAX);
+
+    int k = 0;
+    while (k < PA_CHANNELS_MAX && p[k]) {
+        m.channels = k + 1;
+        m.map[k] = pa_channel_position_from_string(p[k]);
+        k ++;
+    }
+
+    g_strfreev(p);
+    *map = m;
+    return map;
+}
+
+APULSE_EXPORT
 char *
 pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map)
 {
@@ -122,63 +252,36 @@
 }
 
 APULSE_EXPORT
+pa_channel_position_t
+pa_channel_position_from_string(const char *s)
+{
+    trace_info("F %s s=%s\n", __func__, s);
+
+    if (!s)
+        return PA_CHANNEL_POSITION_INVALID;
+
+    for (unsigned int k = 0; k < PA_CHANNEL_POSITION_MAX; k ++) {
+        if (!channel_name[k])
+            continue;
+        if (strcmp(channel_name[k], s) == 0)
+            return k;
+    }
+
+    return PA_CHANNEL_POSITION_INVALID;
+}
+
+APULSE_EXPORT
 const char *
 pa_channel_position_to_string(pa_channel_position_t pos)
 {
     trace_info("F %s pos=%u\n", __func__, pos);
 
-    switch (pos) {
-    case PA_CHANNEL_POSITION_MONO:                  return "mono";
-    case PA_CHANNEL_POSITION_FRONT_CENTER:          return "front-center";
-    case PA_CHANNEL_POSITION_FRONT_LEFT:            return "front-left";
-    case PA_CHANNEL_POSITION_FRONT_RIGHT:           return "front-right";
-    case PA_CHANNEL_POSITION_REAR_CENTER:           return "rear-center";
-    case PA_CHANNEL_POSITION_REAR_LEFT:             return "rear-left";
-    case PA_CHANNEL_POSITION_REAR_RIGHT:            return "rear-right";
-    case PA_CHANNEL_POSITION_LFE:                   return "lfe";
-    case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:  return 
"front-left-of-center";
-    case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: return 
"front-right-of-center";
-    case PA_CHANNEL_POSITION_SIDE_LEFT:             return "side-left";
-    case PA_CHANNEL_POSITION_SIDE_RIGHT:            return "side-right";
-    case PA_CHANNEL_POSITION_AUX0:                  return "aux0";
-    case PA_CHANNEL_POSITION_AUX1:                  return "aux1";
-    case PA_CHANNEL_POSITION_AUX2:                  return "aux2";
-    case PA_CHANNEL_POSITION_AUX3:                  return "aux3";
-    case PA_CHANNEL_POSITION_AUX4:                  return "aux4";
-    case PA_CHANNEL_POSITION_AUX5:                  return "aux5";
-    case PA_CHANNEL_POSITION_AUX6:                  return "aux6";
-    case PA_CHANNEL_POSITION_AUX7:                  return "aux7";
-    case PA_CHANNEL_POSITION_AUX8:                  return "aux8";
-    case PA_CHANNEL_POSITION_AUX9:                  return "aux9";
-    case PA_CHANNEL_POSITION_AUX10:                 return "aux10";
-    case PA_CHANNEL_POSITION_AUX11:                 return "aux11";
-    case PA_CHANNEL_POSITION_AUX12:                 return "aux12";
-    case PA_CHANNEL_POSITION_AUX13:                 return "aux13";
-    case PA_CHANNEL_POSITION_AUX14:                 return "aux14";
-    case PA_CHANNEL_POSITION_AUX15:                 return "aux15";
-    case PA_CHANNEL_POSITION_AUX16:                 return "aux16";
-    case PA_CHANNEL_POSITION_AUX17:                 return "aux17";
-    case PA_CHANNEL_POSITION_AUX18:                 return "aux18";
-    case PA_CHANNEL_POSITION_AUX19:                 return "aux19";
-    case PA_CHANNEL_POSITION_AUX20:                 return "aux20";
-    case PA_CHANNEL_POSITION_AUX21:                 return "aux21";
-    case PA_CHANNEL_POSITION_AUX22:                 return "aux22";
-    case PA_CHANNEL_POSITION_AUX23:                 return "aux23";
-    case PA_CHANNEL_POSITION_AUX24:                 return "aux24";
-    case PA_CHANNEL_POSITION_AUX25:                 return "aux25";
-    case PA_CHANNEL_POSITION_AUX26:                 return "aux26";
-    case PA_CHANNEL_POSITION_AUX27:                 return "aux27";
-    case PA_CHANNEL_POSITION_AUX28:                 return "aux28";
-    case PA_CHANNEL_POSITION_AUX29:                 return "aux29";
-    case PA_CHANNEL_POSITION_AUX30:                 return "aux30";
-    case PA_CHANNEL_POSITION_AUX31:                 return "aux31";
-    case PA_CHANNEL_POSITION_TOP_CENTER:            return "top-center";
-    case PA_CHANNEL_POSITION_TOP_FRONT_CENTER:      return "top-front-center";
-    case PA_CHANNEL_POSITION_TOP_FRONT_LEFT:        return "top-front-left";
-    case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT:       return "top-front-right";
-    case PA_CHANNEL_POSITION_TOP_REAR_CENTER:       return "top-rear-center";
-    case PA_CHANNEL_POSITION_TOP_REAR_LEFT:         return "top-rear-left";
-    case PA_CHANNEL_POSITION_TOP_REAR_RIGHT:        return "top-rear-right";
-    default:                                        return "unknown";
-    }
+    if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
+        return "unknown";
+
+    const char *s = channel_name[pos];
+    if (!s)
+        return "unknown";
+
+    return s;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/apulse-context.c 
new/apulse-0.1.7/src/apulse-context.c
--- old/apulse-0.1.6/src/apulse-context.c       2015-05-25 20:19:11.000000000 
+0200
+++ new/apulse-0.1.7/src/apulse-context.c       2015-12-19 20:45:50.000000000 
+0100
@@ -232,17 +232,21 @@
 pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, const 
pa_cvolume *volume,
                                       pa_context_success_cb_t cb, void 
*userdata)
 {
-    trace_info("Z %s c=%p, idx=%u, volume=%p, cb=%p, userdata=%p\n", __func__, 
c, idx, volume,
+    gchar *s_volume = trace_pa_volume_as_string(volume);
+    trace_info("Z %s c=%p, idx=%u, volume=%s, cb=%p, userdata=%p\n", __func__, 
c, idx, s_volume,
                cb, userdata);
+    g_free(s_volume);
 
-    return NULL;
+    // TODO: actually change volume
+    return pa_operation_new(c->mainloop_api, 
PAOP_CONTEXT_SET_SOURCE_VOLUME_BY_INDEX, c,
+                            NULL, cb, userdata);
 }
 
 APULSE_EXPORT
 void
 pa_context_set_subscribe_callback(pa_context *c, pa_context_subscribe_cb_t cb, 
void *userdata)
 {
-    trace_info("Z %s\n", __func__);
+    trace_info("Z %s c=%p, cb=%p, userdata=%p\n", __func__, c, cb, userdata);
 }
 
 APULSE_EXPORT
@@ -250,7 +254,7 @@
 pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, 
pa_context_success_cb_t cb,
                      void *userdata)
 {
-    trace_info("Z %s\n", __func__);
+    trace_info("Z %s c=%p, m=0x%04x, cb=%p, userdata=%p\n", __func__, c, m, 
cb, userdata);
 
     return NULL;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/apulse-misc.c 
new/apulse-0.1.7/src/apulse-misc.c
--- old/apulse-0.1.6/src/apulse-misc.c  2015-05-25 20:19:11.000000000 +0200
+++ new/apulse-0.1.7/src/apulse-misc.c  2015-12-19 20:45:50.000000000 +0100
@@ -140,9 +140,13 @@
 pa_cvolume *
 pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v)
 {
-    trace_info("Z %s a=%p, channels=%u, v=%u\n", __func__, a, channels, v);
+    trace_info("F %s a=%p, channels=%u, v=%u\n", __func__, a, channels, v);
 
-    return NULL;
+    a->channels = MIN(channels, PA_CHANNELS_MAX);
+    for (unsigned int k = 0; k < a->channels; k ++)
+        a->values[k] = CLAMP(v, PA_VOLUME_MUTED, PA_VOLUME_MAX);
+
+    return a;
 }
 
 APULSE_EXPORT
@@ -234,3 +238,33 @@
 
     return strdup(str);
 }
+
+APULSE_EXPORT
+char *
+pa_get_binary_name(char *s, size_t len)
+{
+    trace_info("F %s s=%p, len=%d\n", __func__, s, (int)len);
+
+    if (len == 0)
+        return NULL;
+
+    char fullpath[PATH_MAX];
+    ssize_t flen = readlink("/proc/self/exe", fullpath, sizeof(fullpath) - 1);
+
+    if (flen < 0)
+        return NULL;
+
+    // ensure fullpath ends with '\0'
+    flen = MIN(flen, sizeof(fullpath) - 1);
+    fullpath[flen] = 0;
+
+    char *name = basename(fullpath);
+    size_t name_len = strlen(name);
+
+    // copy no more than len bytes to s
+    name_len = MIN(name_len, len - 1);
+    memcpy(s, name, name_len);
+    s[name_len] = 0;
+
+    return s;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/apulse-operation.c 
new/apulse-0.1.7/src/apulse-operation.c
--- old/apulse-0.1.6/src/apulse-operation.c     2015-05-25 20:19:11.000000000 
+0200
+++ new/apulse-0.1.7/src/apulse-operation.c     2015-12-19 20:45:50.000000000 
+0100
@@ -91,6 +91,11 @@
         if (o->cb)
             ((pa_stream_success_cb_t)o->cb)(s, 1, o->cb_userdata);
         break;
+    case PAOP_CONTEXT_SET_SOURCE_VOLUME_BY_INDEX:
+        c = o->obj;
+        if (o->cb)
+            ((pa_context_success_cb_t)o->cb)(c, 1, o->cb_userdata);
+        break;
     default:
         break;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/apulse-proplist.c 
new/apulse-0.1.7/src/apulse-proplist.c
--- old/apulse-0.1.6/src/apulse-proplist.c      2015-05-25 20:19:11.000000000 
+0200
+++ new/apulse-0.1.7/src/apulse-proplist.c      2015-12-19 20:45:50.000000000 
+0100
@@ -26,6 +26,11 @@
 #include "trace.h"
 
 
+struct prop {
+    size_t  len;
+    char   *data;
+};
+
 APULSE_EXPORT
 void
 pa_proplist_free(pa_proplist* p)
@@ -43,6 +48,16 @@
     free(data);
 }
 
+static
+void
+prop_destroy_func(gpointer data)
+{
+    struct prop *p = data;
+
+    free(p->data);
+    g_slice_free1(sizeof(*p), p);
+}
+
 APULSE_EXPORT
 pa_proplist *
 pa_proplist_new(void)
@@ -51,17 +66,40 @@
 
     pa_proplist *p = calloc(1, sizeof(pa_proplist));
     p->ht = g_hash_table_new_full(g_str_hash, g_str_equal,
-                                  string_destroy_func, string_destroy_func);
+                                  string_destroy_func, prop_destroy_func);
     return p;
 }
 
 APULSE_EXPORT
 int
+pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t 
nbytes)
+{
+    trace_info("F %s p=%p, key=%s, data=%p, nbytes=%d\n", __func__, p, key, 
data, (int)nbytes);
+
+    struct prop *v = g_slice_alloc(sizeof(*v));
+    if (!v)
+        return -1;
+
+    v->data = g_memdup(data, nbytes);
+    v->len = nbytes;
+
+    g_hash_table_insert(p->ht, strdup(key), v);
+    return 0;
+}
+
+APULSE_EXPORT
+int
 pa_proplist_sets(pa_proplist *p, const char *key, const char *value)
 {
     trace_info("F %s p=%p, key=%s, value=%s\n", __func__, p, key, value);
 
-    g_hash_table_insert(p->ht, strdup(key), strdup(value));
+    struct prop *v = g_slice_alloc(sizeof(*v));
+    if (!v)
+        return -1;
+    v->data = strdup(value);
+    v->len = strlen(value) + 1;
+
+    g_hash_table_insert(p->ht, strdup(key), v);
     return 0;
 }
 
@@ -93,5 +131,17 @@
 pa_proplist_gets(pa_proplist *p, const char *key)
 {
     trace_info("F %s p=%p, key=%s\n", __func__, p, key);
-    return g_hash_table_lookup(p->ht, key);
+
+    struct prop *v = g_hash_table_lookup(p->ht, key);
+
+    if (!v)
+        return NULL;
+
+    if (v->len == 0)
+        return NULL;
+
+    if (v->data[v->len - 1] != '\0')
+        return NULL; // not a string
+
+    return v->data;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/apulse-stream.c 
new/apulse-0.1.7/src/apulse-stream.c
--- old/apulse-0.1.6/src/apulse-stream.c        2015-05-25 20:19:11.000000000 
+0200
+++ new/apulse-0.1.7/src/apulse-stream.c        2015-12-19 20:45:50.000000000 
+0100
@@ -190,9 +190,6 @@
     unsigned int period_time = 20 * 1000;
     dir = 1;
     CHECK_A(snd_pcm_hw_params_set_period_time_near, (s->ph, hw_params, 
&period_time, &dir));
-    dir = -1;
-    snd_pcm_uframes_t period_size;
-    CHECK_A(snd_pcm_hw_params_get_period_size, (hw_params, &period_size, 
&dir));
 
     unsigned int buffer_time = 4 * period_time;
     dir = 1;
@@ -202,6 +199,8 @@
 
     CHECK_A(snd_pcm_sw_params_malloc, (&sw_params));
     CHECK_A(snd_pcm_sw_params_current, (s->ph, sw_params));
+
+    const snd_pcm_uframes_t period_size = (uint64_t)period_time * rate / (1000 
* 1000);
     CHECK_A(snd_pcm_sw_params_set_avail_min, (s->ph, sw_params, period_size));
     // no period event requested
     CHECK_A(snd_pcm_sw_params, (s->ph, sw_params));
@@ -235,6 +234,39 @@
 
 APULSE_EXPORT
 int
+pa_stream_begin_write(pa_stream *p, void **data, size_t *nbytes)
+{
+    trace_info("F %s p=%p\n", __func__, p);
+
+    free(p->write_buffer);
+
+    if (*nbytes == (size_t)-1)
+        *nbytes = 8192;
+
+    p->write_buffer = malloc(*nbytes);
+
+    if (!p->write_buffer)
+        return -1;
+
+    *data = p->write_buffer;
+
+    return 0;
+}
+
+APULSE_EXPORT
+int
+pa_stream_cancel_write(pa_stream *p)
+{
+    trace_info("F %s p=%p\n", __func__, p);
+
+    free(p->write_buffer);
+    p->write_buffer = NULL;
+
+    return 0;
+}
+
+APULSE_EXPORT
+int
 pa_stream_connect_playback(pa_stream *s, const char *dev, const pa_buffer_attr 
*attr,
                            pa_stream_flags_t flags, const pa_cvolume *volume,
                            pa_stream *sync_stream)
@@ -474,7 +506,7 @@
     s->timing_info.configured_source_usec = 0;
     s->timing_info.since_underrun = 0;
 
-    s->rb = ringbuffer_new(50 * 1024);    // TODO: figure out size
+    s->rb = ringbuffer_new(72 * 1024);    // TODO: figure out size
     s->peek_buffer = malloc(s->rb->end - s->rb->start);
 
     return s;
@@ -550,6 +582,7 @@
         g_hash_table_remove(s->c->streams_ht, GINT_TO_POINTER(s->idx));
         ringbuffer_free(s->rb);
         free(s->peek_buffer);
+        free(s->write_buffer);
         free(s->name);
         free(s);
     }
@@ -570,7 +603,19 @@
 {
     trace_info("F %s s=%p\n", __func__, s);
 
-    return ringbuffer_writable_size(s->rb);
+    size_t writable_size = ringbuffer_writable_size(s->rb);
+
+    // Some applications try to push more data than reported to be available
+    // by pa_stream_writable_size(), which is fine for original PulseAudio
+    // but is a severe error in this implementation, since buffer size is
+    // limited.
+    //
+    // Workaround issue by reserving certain amount for that case.
+
+    const size_t limit = 16 * 1024; // TODO: adaptive values?
+
+    return writable_size >= limit ? writable_size
+                                  : 0;
 }
 
 APULSE_EXPORT
@@ -597,8 +642,14 @@
     size_t written = ringbuffer_write(s->rb, data, nbytes);
     s->timing_info.since_underrun += written;
     s->timing_info.write_index += written;
-    if (free_cb)
-        free_cb((void *)data);
+
+    if (data == s->write_buffer) {
+        free(s->write_buffer);
+        s->write_buffer = NULL;
+    } else {
+        if (free_cb)
+            free_cb((void *)data);
+    }
 
     return 0;
 }
@@ -656,12 +707,21 @@
 uint32_t
 pa_stream_get_device_index(pa_stream *s)
 {
-    trace_info("Z %s s=%p\n", __func__, s);
+    trace_info("F %s s=%p\n", __func__, s);
 
+    // apulse uses only one sink -- ALSA device, so index is always 0
     return 0;
 }
 
 APULSE_EXPORT
+const char *
+pa_stream_get_device_name(pa_stream *s)
+{
+    trace_info("F %s s=%p\n", __func__, s);
+    return "apulse";
+}
+
+APULSE_EXPORT
 int
 pa_stream_peek(pa_stream *s, const void **data, size_t *nbytes)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/apulse.h 
new/apulse-0.1.7/src/apulse.h
--- old/apulse-0.1.6/src/apulse.h       2015-05-25 20:19:11.000000000 +0200
+++ new/apulse-0.1.7/src/apulse.h       2015-12-19 20:45:50.000000000 +0100
@@ -44,6 +44,7 @@
     PAOP_STREAM_TRIGGER,
     PAOP_STREAM_UPD_TIMING_INFO,
     PAOP_CONTEXT_GET_SINK_INFO,
+    PAOP_CONTEXT_SET_SOURCE_VOLUME_BY_INDEX,
 };
 
 struct pa_context {
@@ -120,6 +121,7 @@
     ringbuffer_t           *rb;
     void                   *peek_buffer;
     size_t                  peek_buffer_data_len;
+    void                   *write_buffer;
     volatile int            paused;
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/notimplemented.c 
new/apulse-0.1.7/src/notimplemented.c
--- old/apulse-0.1.6/src/notimplemented.c       2015-05-25 20:19:11.000000000 
+0200
+++ new/apulse-0.1.7/src/notimplemented.c       2015-12-19 20:45:50.000000000 
+0100
@@ -104,13 +104,6 @@
 }
 
 APULSE_EXPORT
-int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t 
nbytes)
-{
-    trace_info("Z %s\n", __func__);
-    return 0;
-}
-
-APULSE_EXPORT
 int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t 
*nbytes)
 {
     trace_info("Z %s\n", __func__);
@@ -195,13 +188,6 @@
 }
 
 APULSE_EXPORT
-pa_channel_position_t pa_channel_position_from_string(const char *s)
-{
-    trace_info("Z %s\n", __func__);
-    return 0;
-}
-
-APULSE_EXPORT
 const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos)
 {
     trace_info("Z %s\n", __func__);
@@ -209,13 +195,6 @@
 }
 
 APULSE_EXPORT
-pa_channel_map *pa_channel_map_parse(pa_channel_map *map, const char *s)
-{
-    trace_info("Z %s\n", __func__);
-    return NULL;
-}
-
-APULSE_EXPORT
 int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b)
 {
     trace_info("Z %s\n", __func__);
@@ -809,27 +788,6 @@
 }
 
 APULSE_EXPORT
-const char *pa_stream_get_device_name(pa_stream *s)
-{
-    trace_info("Z %s\n", __func__);
-    return NULL;
-}
-
-APULSE_EXPORT
-int pa_stream_begin_write(pa_stream *p, void **data, size_t *nbytes)
-{
-    trace_info("Z %s\n", __func__);
-    return 0;
-}
-
-APULSE_EXPORT
-int pa_stream_cancel_write(pa_stream *p)
-{
-    trace_info("Z %s\n", __func__);
-    return 0;
-}
-
-APULSE_EXPORT
 void pa_stream_set_overflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, 
void *userdata)
 {
     trace_info("Z %s\n", __func__);
@@ -1463,13 +1421,6 @@
 {
     trace_info("Z %s\n", __func__);
     return NULL;
-}
-
-APULSE_EXPORT
-char *pa_get_binary_name(char *s, size_t l)
-{
-    trace_info("Z %s\n", __func__);
-    return NULL;
 }
 
 APULSE_EXPORT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/trace.c new/apulse-0.1.7/src/trace.c
--- old/apulse-0.1.6/src/trace.c        2015-05-25 20:19:11.000000000 +0200
+++ new/apulse-0.1.7/src/trace.c        2015-12-19 20:45:50.000000000 +0100
@@ -93,6 +93,25 @@
     return res;
 }
 
+gchar *
+trace_pa_volume_as_string(const pa_cvolume *v)
+{
+    const unsigned int channel_count = MIN(v->channels, PA_CHANNELS_MAX);
+    GString *s = g_string_new(NULL);
+
+    g_string_append_printf(s, "%d:{", v->channels);
+    for (unsigned int k = 0; k < channel_count ; k ++) {
+        if (k != 0)
+            g_string_append(s, ", ");
+
+        g_string_append_printf(s, "%u", v->values[k]);
+    }
+
+    g_string_append(s, "}");
+
+    return g_string_free(s, FALSE);
+}
+
 void
 trace_lock(void)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apulse-0.1.6/src/trace.h new/apulse-0.1.7/src/trace.h
--- old/apulse-0.1.6/src/trace.h        2015-05-25 20:19:11.000000000 +0200
+++ new/apulse-0.1.7/src/trace.h        2015-12-19 20:45:50.000000000 +0100
@@ -36,6 +36,9 @@
 gchar *
 trace_pa_buffer_attr_as_string(const pa_buffer_attr *attr);
 
+gchar *
+trace_pa_volume_as_string(const pa_cvolume *v);
+
 void
 trace_lock(void);
 


Reply via email to