You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
4.3 KiB
172 lines
4.3 KiB
/*
|
|
Calf Box, an open source musical instrument.
|
|
Copyright (C) 2010 Krzysztof Foltman
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#if USE_JACK
|
|
|
|
#include "config-api.h"
|
|
#include "io.h"
|
|
|
|
#include <glib.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/stat.h>
|
|
|
|
static char *cfg(const char *section, const char *name, char *defvalue)
|
|
{
|
|
char *value = cbox_config_get_string(section, name);
|
|
if (value)
|
|
return value;
|
|
return cbox_config_get_string_with_default("autojack", name, defvalue);
|
|
}
|
|
|
|
static void generate_jack_config(const char *section, const char *id)
|
|
{
|
|
char *rcfile = cbox_config_get_string("autojack", "jackdrc");
|
|
FILE *f;
|
|
if (!rcfile)
|
|
{
|
|
rcfile = g_strdup_printf("%s/.jackdrc", getenv("HOME"));
|
|
g_message("Generating JACK config: %s\n", rcfile);
|
|
f = fopen(rcfile, "w");
|
|
if (!f)
|
|
{
|
|
g_error("Cannot open file %s", rcfile);
|
|
return;
|
|
}
|
|
g_free(rcfile);
|
|
}
|
|
else
|
|
{
|
|
g_message("Generating JACK config: %s\n", rcfile);
|
|
f = fopen(rcfile, "w");
|
|
if (!f)
|
|
{
|
|
g_error("Cannot open file %s", rcfile);
|
|
return;
|
|
}
|
|
}
|
|
|
|
fprintf(f, "%s %s -d alsa -d hw:%s -r 44100 %s\n",
|
|
cfg(section, "jackd", "/usr/bin/jackd"),
|
|
cfg(section, "jack_options", "-R -T"),
|
|
id,
|
|
cfg(section, "alsa_options", ""));
|
|
fclose(f);
|
|
}
|
|
|
|
static int try_soundcard(const char *name)
|
|
{
|
|
gchar *id;
|
|
if (!cbox_config_has_section(name))
|
|
return 0;
|
|
|
|
g_message("Trying section %s", name);
|
|
|
|
id = cbox_config_get_string(name, "device");
|
|
if (id != NULL)
|
|
{
|
|
struct stat s;
|
|
int result;
|
|
gchar *fn = g_strdup_printf("/proc/asound/%s", id);
|
|
result = stat(fn, &s);
|
|
if (!result)
|
|
generate_jack_config(name, id);
|
|
g_free(fn);
|
|
return !result;
|
|
}
|
|
|
|
id = cbox_config_get_string(name, "usbid");
|
|
if (id != NULL)
|
|
{
|
|
int vid, pid;
|
|
if (sscanf(id, "%x:%x\n", &vid, &pid) !=2)
|
|
{
|
|
g_error("Invalid VID:PID value: %s", id);
|
|
return 0;
|
|
}
|
|
for (int i = 0; ; i++)
|
|
{
|
|
struct stat s;
|
|
int result;
|
|
FILE *f = NULL;
|
|
int tvid, tpid;
|
|
|
|
// check if it's not beyond the last soundcard index
|
|
gchar *fn = g_strdup_printf("/proc/asound/card%d", i);
|
|
result = stat(fn, &s);
|
|
g_free(fn);
|
|
if (result)
|
|
break;
|
|
|
|
// check if it has a USB ID
|
|
fn = g_strdup_printf("/proc/asound/card%d/usbid", i);
|
|
f = fopen(fn, "r");
|
|
g_free(fn);
|
|
|
|
if (!f)
|
|
continue;
|
|
|
|
if (fscanf(f, "%x:%x", &tvid, &tpid) == 2)
|
|
{
|
|
if (vid == tvid && pid == tpid)
|
|
{
|
|
gchar *fn = g_strdup_printf("%d", i);
|
|
generate_jack_config(name, fn);
|
|
g_free(fn);
|
|
fclose(f);
|
|
return 1;
|
|
}
|
|
}
|
|
fclose(f);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cbox_hwcfg_setup_jack(void)
|
|
{
|
|
int i;
|
|
if (!cbox_config_has_section("autojack"))
|
|
return 0;
|
|
|
|
for (i = 0; ; i++)
|
|
{
|
|
int result;
|
|
gchar *cardnum = g_strdup_printf("soundcard%d", i);
|
|
char *secname = cbox_config_get_string("autojack", cardnum);
|
|
g_free(cardnum);
|
|
|
|
if (!secname)
|
|
break;
|
|
|
|
secname = g_strdup_printf("soundcard:%s", secname);
|
|
result = try_soundcard(secname);
|
|
g_free(secname);
|
|
|
|
if (result)
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|