summaryrefslogtreecommitdiff
path: root/debian/patches/0035-stream-restore-simple-fallback-volume-table.patch
blob: ff86a0f5a1b7439d2a97892d3afddadce62d1226 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
From f7df7399497118cbfb6a6035daa1315068b1e17a Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
Date: Fri, 15 May 2009 17:24:54 +0300
Subject: [PATCH 35/85] stream-restore: simple fallback volume table

---
 src/modules/module-stream-restore.c |   94 ++++++++++++++++++++++++++++++++++-
 1 files changed, 93 insertions(+), 1 deletions(-)

diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 4bfc181..4813912 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -60,15 +60,22 @@ PA_MODULE_LOAD_ONCE(TRUE);
 PA_MODULE_USAGE(
         "restore_device=<Save/restore sinks/sources?> "
         "restore_volume=<Save/restore volumes?> "
-        "restore_muted=<Save/restore muted states?>");
+        "restore_muted=<Save/restore muted states?> "
+        "fallback_table=<filename>");
 
 #define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
 #define IDENTIFICATION_PROPERTY "module-stream-restore.id"
 
+#define DEFAULT_FALLBACK_FILE PA_DEFAULT_CONFIG_DIR"/stream-restore.table"
+#define DEFAULT_FALLBACK_FILE_USER "stream-restore.table"
+
+#define WHITESPACE "\n\r \t"
+
 static const char* const valid_modargs[] = {
     "restore_device",
     "restore_volume",
     "restore_muted",
+    "fallback_table",
     NULL
 };
 
@@ -492,6 +499,88 @@ static void clear_db(struct userdata *u) {
     gdbm_reorganize(u->gdbm_file);
 }
 
+static int fill_db(struct userdata *u, const char *filename) {
+    FILE *f;
+    int n = 0;
+    int ret = -1;
+    char *fn = NULL;
+
+    pa_assert(u);
+
+    if (filename)
+        f = fopen(fn = pa_xstrdup(filename), "r");
+    else
+        f = pa_open_config_file(DEFAULT_FALLBACK_FILE, DEFAULT_FALLBACK_FILE_USER, NULL, &fn);
+
+    if (!f) {
+        pa_log("Failed to open file config file: %s", pa_cstrerror(errno));
+        goto finish;
+    }
+
+    pa_lock_fd(fileno(f), 1);
+
+    while (!feof(f)) {
+        char ln[256];
+        char *d, *v;
+        double db;
+
+        if (!fgets(ln, sizeof(ln), f))
+            break;
+
+        n++;
+
+        pa_strip_nl(ln);
+
+        if (ln[0] == '#' || !*ln )
+            continue;
+
+        d = ln+strcspn(ln, WHITESPACE);
+        v = d+strspn(d, WHITESPACE);
+
+        if (!*v) {
+            pa_log(__FILE__ ": [%s:%u] failed to parse line - too few words", filename, n);
+            goto finish;
+        }
+
+        *d = 0;
+        if (pa_atod(v, &db) >= 0) {
+            datum key, data;
+            struct entry e;
+
+            memset(&e, 0, sizeof(e));
+            e.version = ENTRY_VERSION;
+            e.volume_valid = TRUE;
+            pa_cvolume_set(&e.volume, 1, pa_sw_volume_from_dB(db));
+            pa_channel_map_init_mono(&e.channel_map);
+            e.volume_is_absolute = TRUE;
+            e.volume_is_absolute_valid = TRUE;
+
+            key.dptr = (void*) ln;
+            key.dsize = (int) strlen(ln);
+
+            data.dptr = (void*) &e;
+            data.dsize = sizeof(e);
+
+            if (gdbm_store(u->gdbm_file, key, data, GDBM_INSERT) == 0)
+                pa_log_debug("Setting %s to %fdb", ln, db);
+        }
+    }
+
+    trigger_save(u);
+    ret = 0;
+
+finish:
+    if (f) {
+        pa_lock_fd(fileno(f), 0);
+        fclose(f);
+    }
+
+    if (fn)
+        pa_xfree(fn);
+
+    return ret;
+}
+
 static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
     pa_sink_input *si;
     pa_source_output *so;
@@ -872,6 +961,9 @@ int pa__init(pa_module*m) {
     pa_log_info("Sucessfully opened database file '%s'.", fname);
     pa_xfree(fname);
 
+    if (fill_db(u, pa_modargs_get_value(ma, "fallback_table", NULL)) < 0)
+        goto fail;
+
     for (si = pa_idxset_first(m->core->sink_inputs, &idx); si; si = pa_idxset_next(m->core->sink_inputs, &idx))
         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, si->index, u);
 
-- 
1.6.3.3