Fix broken bounds check.
[calfbox.git] / hwcfg.c
blobb86cb7b121c8a25c77ce2a912e2646cfe254885c
1 /*
2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010 Krzysztof Foltman
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "config.h"
21 #if USE_JACK
23 #include "config-api.h"
24 #include "io.h"
26 #include <glib.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <sys/stat.h>
31 static char *cfg(const char *section, const char *name, char *defvalue)
33 char *value = cbox_config_get_string(section, name);
34 if (value)
35 return value;
36 return cbox_config_get_string_with_default("autojack", name, defvalue);
39 static void generate_jack_config(const char *section, const char *id)
41 char *rcfile = cbox_config_get_string("autojack", "jackdrc");
42 FILE *f;
43 if (!rcfile)
45 rcfile = g_strdup_printf("%s/.jackdrc", getenv("HOME"));
46 g_message("Generating JACK config: %s\n", rcfile);
47 f = fopen(rcfile, "w");
48 if (!f)
50 g_error("Cannot open file %s", rcfile);
51 return;
53 g_free(rcfile);
55 else
57 g_message("Generating JACK config: %s\n", rcfile);
58 f = fopen(rcfile, "w");
59 if (!f)
61 g_error("Cannot open file %s", rcfile);
62 return;
66 fprintf(f, "%s %s -d alsa -d hw:%s -r 44100 %s\n",
67 cfg(section, "jackd", "/usr/bin/jackd"),
68 cfg(section, "jack_options", "-R -T"),
69 id,
70 cfg(section, "alsa_options", ""));
71 fclose(f);
74 static int try_soundcard(const char *name)
76 gchar *id;
77 if (!cbox_config_has_section(name))
78 return 0;
80 g_message("Trying section %s", name);
82 id = cbox_config_get_string(name, "device");
83 if (id != NULL)
85 struct stat s;
86 int result;
87 gchar *fn = g_strdup_printf("/proc/asound/%s", id);
88 result = stat(fn, &s);
89 if (!result)
90 generate_jack_config(name, id);
91 g_free(fn);
92 return !result;
95 id = cbox_config_get_string(name, "usbid");
96 if (id != NULL)
98 int vid, pid;
99 if (sscanf(id, "%x:%x\n", &vid, &pid) !=2)
101 g_error("Invalid VID:PID value: %s", id);
102 return 0;
104 for (int i = 0; ; i++)
106 struct stat s;
107 int result;
108 FILE *f = NULL;
109 int tvid, tpid;
111 // check if it's not beyond the last soundcard index
112 gchar *fn = g_strdup_printf("/proc/asound/card%d", i);
113 result = stat(fn, &s);
114 g_free(fn);
115 if (result)
116 break;
118 // check if it has a USB ID
119 fn = g_strdup_printf("/proc/asound/card%d/usbid", i);
120 f = fopen(fn, "r");
121 g_free(fn);
123 if (!f)
124 continue;
126 if (fscanf(f, "%x:%x", &tvid, &tpid) == 2)
128 if (vid == tvid && pid == tpid)
130 gchar *fn = g_strdup_printf("%d", i);
131 generate_jack_config(name, fn);
132 g_free(fn);
133 fclose(f);
134 return 1;
137 fclose(f);
139 return 0;
142 return 0;
145 int cbox_hwcfg_setup_jack(void)
147 int i;
148 if (!cbox_config_has_section("autojack"))
149 return 0;
151 for (i = 0; ; i++)
153 int result;
154 gchar *cardnum = g_strdup_printf("soundcard%d", i);
155 char *secname = cbox_config_get_string("autojack", cardnum);
156 g_free(cardnum);
158 if (!secname)
159 break;
161 secname = g_strdup_printf("soundcard:%s", secname);
162 result = try_soundcard(secname);
163 g_free(secname);
165 if (result)
166 return 1;
169 return 0;
172 #endif