summaryrefslogtreecommitdiff
path: root/trivmix.c
diff options
context:
space:
mode:
Diffstat (limited to 'trivmix.c')
-rw-r--r--trivmix.c296
1 files changed, 0 insertions, 296 deletions
diff --git a/trivmix.c b/trivmix.c
deleted file mode 100644
index 720c409..0000000
--- a/trivmix.c
+++ /dev/null
@@ -1,296 +0,0 @@
1#include <stdio.h>
2#include <errno.h>
3#include <math.h>
4#include <string.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <libgen.h>
8#include <sys/stat.h>
9#include <sys/inotify.h>
10#include <signal.h>
11
12#include "trivmix.h"
13
14#define PIDFILE "pid"
15#define INPUTFILE "input"
16#define OUTPUTFILE "output"
17#define NAMEFILE "name"
18#define GAINFILE "gain"
19#define DIRMODE S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
20#define FILEMODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
21#define INOTIFYBUFLEN 1024 * (sizeof(struct inotify_event) + 16)
22#define NOTIFYMASK IN_MODIFY | IN_CREATE | IN_DELETE | IN_ONESHOT
23
24mixState state = { .input = NULL, .output = NULL, .name = NULL, .dBGain = -90 };
25char *workdir;
26char *inotifyBuffer;
27bool changedDir = false;
28
29void initState()
30{
31 const char *defaultName = "mixer";
32
33 state.input = malloc(sizeof(char));
34 *(state.input) = '\0';
35 state.output = malloc(sizeof(char));
36 *(state.output) = '\0';
37 state.name = malloc(sizeof(char) * (1 + strlen(defaultName)));
38 strcpy(state.name, defaultName);
39}
40
41void signalHandler(int signal)
42{
43 fprintf(stderr, "Received signal: %d\n", signal);
44 cleanExit(1);
45}
46
47void setupSignalHandler()
48{
49 signal(SIGABRT, signalHandler);
50 signal(SIGFPE, SIG_IGN);
51 signal(SIGILL, SIG_IGN);
52 signal(SIGINT, signalHandler);
53 signal(SIGTERM, signalHandler);
54 signal(SIGSEGV, signalHandler);
55}
56
57void parseArgs(int argc, char *argv[])
58{
59 char opt;
60
61 while ((opt = getopt(argc, argv, "g:n:i:o:")) != -1)
62 {
63 switch (opt)
64 {
65 case 'g':
66 sscanf(optarg, "%f", &(state.dBGain));
67 break;
68 case 'n':
69 state.name = realloc(state.name, sizeof(char) * (1 + strlen(optarg)));
70 strcpy(state.name, optarg);
71 break;
72 case 'i':
73 state.input = realloc(state.input, sizeof(char) * (1 + strlen(optarg)));
74 strcpy(state.input, optarg);
75 break;
76 case 'o':
77 state.output = realloc(state.output, sizeof(char) * (1 + strlen(optarg)));
78 strcpy(state.output, optarg);
79 break;
80 }
81 }
82
83 if (optind > argc - 1)
84 {
85 fprintf(stderr, "Usage: %s [-g {gain}] [-n {name}] [-i {input}] [-o {output}] {working directory}\n", argv[0]);
86 cleanExit(2);
87 }
88
89 workdir = argv[optind++];
90}
91
92void setWorkdir()
93{
94 if (!(mkdir(workdir, DIRMODE) == 0 || errno == EEXIST) || chdir(workdir) == -1)
95 errMsg(1, &errno, "Failed to change to workdir", workdir);
96 changedDir = true;
97}
98
99void writePid()
100{
101 FILE *pidFile;
102
103 openSyncFile(&pidFile, PIDFILE, "wx", false);
104 if (fprintf(pidFile, "%d\n", getpid()) <= 1)
105 errMsg(1, &errno, "Failed to write to pidfile", PIDFILE);
106 fclose(pidFile);
107}
108
109void syncState()
110{
111 readState();
112 writeState();
113}
114
115void readState()
116{
117 FILE *pidFile;
118 FILE *inputFile;
119 FILE *outputFile;
120 FILE *nameFile;
121 FILE *gainFile;
122 int newInt;
123 char newString[64];
124 float newFloat;
125 int ret;
126
127 if (openSyncFile(&pidFile, PIDFILE, "r", true) == -1)
128 {
129 ret = fscanf(pidFile, "%d", &newInt);
130 fclose(pidFile);
131
132 if (ret == 0 || ret == EOF || newInt != getpid())
133 cleanExit(0);
134 }
135 else
136 cleanExit(0);
137
138 if (openSyncFile(&inputFile, INPUTFILE, "r", true) == -1)
139 {
140 ret = fscanf(inputFile, "%63s", newString);
141 fclose(inputFile);
142
143 if (ret != 0 && ret != EOF)
144 {
145 // TODO Try to set new jack input here
146 state.input = realloc(state.input, sizeof(char) * (1 + strlen(newString)));
147 strcpy(state.input, newString);
148 }
149 }
150 if (openSyncFile(&outputFile, OUTPUTFILE, "r", true) == -1)
151 {
152 ret = fscanf(outputFile, "%63s", newString);
153 fclose(outputFile);
154
155 if (ret != 0 && ret != EOF)
156 {
157 // TODO Try to set new jack output here
158 state.output = realloc(state.output, sizeof(char) * (1 + strlen(newString)));
159 strcpy(state.output, newString);
160 }
161 }
162
163 if (openSyncFile(&gainFile, GAINFILE, "r", true) == -1)
164 {
165 ret = fscanf(gainFile, "%f", &newFloat);
166 fclose(gainFile);
167
168 if (ret != 0 && ret != EOF)
169 {
170 if (newFloat < -90)
171 newFloat = -90;
172 state.dBGain = newFloat;
173 }
174 }
175}
176
177void writeState()
178{
179 FILE *pidFile;
180 FILE *inputFile;
181 FILE *outputFile;
182 FILE *nameFile;
183 FILE *gainFile;
184 int ret;
185
186 openSyncFile(&pidFile, PIDFILE, "w", false);
187 ret = fprintf(pidFile, "%d\n", getpid());
188 if (ret < 1)
189 errMsg(1, &errno, "Failed to write pidfile", PIDFILE);
190 fclose(pidFile);
191
192 openSyncFile(&inputFile, INPUTFILE, "w", false);
193 ret = fprintf(inputFile, "%s\n", state.input);
194 if (ret < 1)
195 errMsg(1, &errno, "Failed to write file", INPUTFILE);
196 fclose(inputFile);
197
198 openSyncFile(&outputFile, OUTPUTFILE, "w", false);
199 ret = fprintf(outputFile, "%s\n", state.output);
200 if (ret < 1)
201 errMsg(1, &errno, "Failed to write file", OUTPUTFILE);
202 fclose(outputFile);
203
204 openSyncFile(&nameFile, NAMEFILE, "w", false);
205 ret = fprintf(nameFile, "%s\n", state.name);
206 if (ret < 1)
207 errMsg(1, &errno, "Failed to write file", NAMEFILE);
208 fclose(nameFile);
209
210 openSyncFile(&gainFile, GAINFILE, "w", false);
211 ret = fprintf(gainFile, "%.2f\n", state.dBGain);
212 if (ret < 1)
213 errMsg(1, &errno, "Failed to write file", GAINFILE);
214 fclose(gainFile);
215}
216
217int openSyncFile(FILE **file, char *fileName, char *fileMode, bool errOK)
218{
219 int ret = -1;
220
221 if ((*file = fopen(fileName, fileMode)) == NULL)
222 {
223 if (errOK == false)
224 errMsg(1, &errno, "Failed to open file", fileName);
225 else
226 {
227 ret = errno;
228 }
229 }
230
231 return ret;
232}
233
234int main(int argc, char *argv[])
235{
236 int inotifyFD;
237
238 initState();
239 inotifyBuffer = malloc(INOTIFYBUFLEN);
240 setupSignalHandler();
241
242 parseArgs(argc, argv);
243 setWorkdir();
244
245 writePid();
246 writeState();
247
248 inotifyFD = inotify_init();
249 if (inotifyFD < 0)
250 errMsg(1, NULL, "Failed to setup inotify", NULL);
251
252 do
253 {
254 syncState();
255 printf("State:\n input = %s\n output = %s\n name = %s\n gain = %.2fdB\n", state.input, state.output, state.name, state.dBGain);
256 inotify_add_watch(inotifyFD, ".", NOTIFYMASK);
257 }
258 while (read(inotifyFD, inotifyBuffer, INOTIFYBUFLEN) >= 0);
259
260 exit(0);
261}
262
263void cleanExit(int r)
264{
265 if (changedDir == true)
266 {
267 if (unlink(PIDFILE) != 0 && errno != ENOENT)
268 errMsg(-1, &errno, "Failed to delete pidfile", PIDFILE);
269 }
270 free(state.input);
271 free(state.output);
272 free(state.name);
273 free(inotifyBuffer);
274 exit(r);
275}
276
277void errMsg(int r, int *errno, char *head, char *detail)
278{
279 int err;
280 bool error = false;
281
282 if (errno != NULL)
283 {
284 error = true;
285 err = *errno;
286 }
287
288 fprintf(stderr, "%s\n", head);
289 if (detail != NULL)
290 fprintf(stderr, " %s\n", detail);
291 if (error == true)
292 fprintf(stderr, " (%d) %s\n", err, strerror(err));
293
294 if (r >= 0)
295 cleanExit(r);
296}