mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-10-06 08:28:00 +02:00
Compare commits
13 commits
a77d607f78
...
6642ee90ef
Author | SHA1 | Date | |
---|---|---|---|
|
6642ee90ef | ||
|
d480eac6f2 | ||
|
c95db638c0 | ||
|
5703d27773 | ||
|
39053b90d5 | ||
|
397c198955 | ||
|
946ea467cf | ||
|
c7b342db82 | ||
|
d26b66f881 | ||
|
cac4935ba2 | ||
|
4aae5a770f | ||
|
cdcfcddd95 | ||
|
ffc63f76de |
7 changed files with 273 additions and 125 deletions
13
configure.ac
13
configure.ac
|
@ -21,7 +21,7 @@ AC_PROG_SED
|
||||||
AC_DISABLE_STATIC
|
AC_DISABLE_STATIC
|
||||||
AM_PROG_LIBTOOL
|
AM_PROG_LIBTOOL
|
||||||
PKG_PROG_PKG_CONFIG
|
PKG_PROG_PKG_CONFIG
|
||||||
AM_PATH_ALSA(1.2.5)
|
AM_PATH_ALSA(1.2.12)
|
||||||
if test "x$enable_alsatest" = "xyes"; then
|
if test "x$enable_alsatest" = "xyes"; then
|
||||||
AC_CHECK_FUNC([snd_ctl_elem_add_enumerated],
|
AC_CHECK_FUNC([snd_ctl_elem_add_enumerated],
|
||||||
, [AC_ERROR([No user enum control support in alsa-lib])])
|
, [AC_ERROR([No user enum control support in alsa-lib])])
|
||||||
|
@ -47,17 +47,6 @@ AC_CHECK_HEADERS([samplerate.h], [have_samplerate="yes"], [have_samplerate="no"]
|
||||||
[#include <samplerate.h>])
|
[#include <samplerate.h>])
|
||||||
|
|
||||||
AC_CHECK_LIB([asound], [snd_seq_client_info_get_card], [HAVE_SEQ_CLIENT_INFO_GET_CARD="yes"])
|
AC_CHECK_LIB([asound], [snd_seq_client_info_get_card], [HAVE_SEQ_CLIENT_INFO_GET_CARD="yes"])
|
||||||
if test "$HAVE_SEQ_CLIENT_INFO_GET_CARD" = "yes" ; then
|
|
||||||
AC_DEFINE([HAVE_SEQ_CLIENT_INFO_GET_CARD], 1, [alsa-lib supports snd_seq_client_info_get_card])
|
|
||||||
fi
|
|
||||||
AC_CHECK_LIB([asound], [snd_seq_client_info_get_pid], [HAVE_SEQ_CLIENT_INFO_GET_PID="yes"])
|
|
||||||
if test "$HAVE_SEQ_CLIENT_INFO_GET_PID" = "yes" ; then
|
|
||||||
AC_DEFINE([HAVE_SEQ_CLIENT_INFO_GET_PID], 1, [alsa-lib supports snd_seq_client_info_get_pid])
|
|
||||||
fi
|
|
||||||
AC_CHECK_LIB([asound], [snd_seq_client_info_get_midi_version], [HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION="yes"])
|
|
||||||
if test "$HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION" = "yes" -a "$have_rawmidi" = "yes"; then
|
|
||||||
AC_DEFINE([HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION], 1, [alsa-lib supports snd_seq_client_info_get_midi_version])
|
|
||||||
fi
|
|
||||||
AC_CHECK_LIB([atopology], [snd_tplg_save], [have_topology="yes"], [have_topology="no"])
|
AC_CHECK_LIB([atopology], [snd_tplg_save], [have_topology="yes"], [have_topology="no"])
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -29,12 +29,7 @@
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
|
|
||||||
#ifdef SND_SEQ_PORT_CAP_INACTIVE
|
|
||||||
#define HANDLE_SHOW_ALL
|
|
||||||
static int show_all;
|
static int show_all;
|
||||||
#else
|
|
||||||
#define show_all 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void error_handler(const char *file, int line, const char *function, int err, const char *fmt, ...)
|
static void error_handler(const char *file, int line, const char *function, int err, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -67,9 +62,7 @@ static void usage(void)
|
||||||
printf(_(" aconnect -i|-o [-options]\n"));
|
printf(_(" aconnect -i|-o [-options]\n"));
|
||||||
printf(_(" -i,--input list input (readable) ports\n"));
|
printf(_(" -i,--input list input (readable) ports\n"));
|
||||||
printf(_(" -o,--output list output (writable) ports\n"));
|
printf(_(" -o,--output list output (writable) ports\n"));
|
||||||
#ifdef HANDLE_SHOW_ALL
|
|
||||||
printf(_(" -a,--all show inactive ports, too\n"));
|
printf(_(" -a,--all show inactive ports, too\n"));
|
||||||
#endif
|
|
||||||
printf(_(" -l,--list list current connections of each port\n"));
|
printf(_(" -l,--list list current connections of each port\n"));
|
||||||
printf(_(" * Remove all exported connections\n"));
|
printf(_(" * Remove all exported connections\n"));
|
||||||
printf(_(" -x, --removeall\n"));
|
printf(_(" -x, --removeall\n"));
|
||||||
|
@ -84,15 +77,11 @@ static void usage(void)
|
||||||
|
|
||||||
#define perm_ok(cap,bits) (((cap) & (bits)) == (bits))
|
#define perm_ok(cap,bits) (((cap) & (bits)) == (bits))
|
||||||
|
|
||||||
#ifdef SND_SEQ_PORT_DIR_INPUT
|
|
||||||
static int check_direction(snd_seq_port_info_t *pinfo, int bit)
|
static int check_direction(snd_seq_port_info_t *pinfo, int bit)
|
||||||
{
|
{
|
||||||
int dir = snd_seq_port_info_get_direction(pinfo);
|
int dir = snd_seq_port_info_get_direction(pinfo);
|
||||||
return !dir || (dir & bit);
|
return !dir || (dir & bit);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#define check_direction(x, y) 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int check_permission(snd_seq_port_info_t *pinfo, int perm)
|
static int check_permission(snd_seq_port_info_t *pinfo, int perm)
|
||||||
{
|
{
|
||||||
|
@ -174,20 +163,16 @@ static void do_search_port(snd_seq_t *seq, int perm, action_func_t do_action)
|
||||||
/* reset query info */
|
/* reset query info */
|
||||||
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
|
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
|
||||||
snd_seq_port_info_set_port(pinfo, -1);
|
snd_seq_port_info_set_port(pinfo, -1);
|
||||||
#ifdef HANDLE_SHOW_ALL
|
|
||||||
if (show_all)
|
if (show_all)
|
||||||
snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_INACTIVE);
|
snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_INACTIVE);
|
||||||
#endif
|
|
||||||
count = 0;
|
count = 0;
|
||||||
while (snd_seq_query_next_port(seq, pinfo) >= 0) {
|
while (snd_seq_query_next_port(seq, pinfo) >= 0) {
|
||||||
if (check_permission(pinfo, perm)) {
|
if (check_permission(pinfo, perm)) {
|
||||||
do_action(seq, cinfo, pinfo, count);
|
do_action(seq, cinfo, pinfo, count);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
#ifdef HANDLE_SHOW_ALL
|
|
||||||
if (show_all)
|
if (show_all)
|
||||||
snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_INACTIVE);
|
snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_INACTIVE);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +190,6 @@ static void print_port(snd_seq_t *seq ATTRIBUTE_UNUSED,
|
||||||
snd_seq_client_info_get_name(cinfo),
|
snd_seq_client_info_get_name(cinfo),
|
||||||
(snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ?
|
(snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ?
|
||||||
_("user") : _("kernel")));
|
_("user") : _("kernel")));
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
switch (snd_seq_client_info_get_midi_version(cinfo)) {
|
switch (snd_seq_client_info_get_midi_version(cinfo)) {
|
||||||
case SND_SEQ_CLIENT_UMP_MIDI_1_0:
|
case SND_SEQ_CLIENT_UMP_MIDI_1_0:
|
||||||
printf(",UMP-MIDI1");
|
printf(",UMP-MIDI1");
|
||||||
|
@ -214,16 +198,11 @@ static void print_port(snd_seq_t *seq ATTRIBUTE_UNUSED,
|
||||||
printf(",UMP-MIDI2");
|
printf(",UMP-MIDI2");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_CARD
|
|
||||||
card = snd_seq_client_info_get_card(cinfo);
|
card = snd_seq_client_info_get_card(cinfo);
|
||||||
#endif
|
|
||||||
if (card != -1)
|
if (card != -1)
|
||||||
printf(",card=%d", card);
|
printf(",card=%d", card);
|
||||||
|
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_PID
|
|
||||||
pid = snd_seq_client_info_get_pid(cinfo);
|
pid = snd_seq_client_info_get_pid(cinfo);
|
||||||
#endif
|
|
||||||
if (pid != -1)
|
if (pid != -1)
|
||||||
printf(",pid=%d", pid);
|
printf(",pid=%d", pid);
|
||||||
printf("]\n");
|
printf("]\n");
|
||||||
|
@ -231,10 +210,8 @@ static void print_port(snd_seq_t *seq ATTRIBUTE_UNUSED,
|
||||||
printf(" %3d '%-16s'",
|
printf(" %3d '%-16s'",
|
||||||
snd_seq_port_info_get_port(pinfo),
|
snd_seq_port_info_get_port(pinfo),
|
||||||
snd_seq_port_info_get_name(pinfo));
|
snd_seq_port_info_get_name(pinfo));
|
||||||
#ifdef HANDLE_SHOW_ALL
|
|
||||||
if (snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_INACTIVE)
|
if (snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_INACTIVE)
|
||||||
printf(" [INACTIVE]");
|
printf(" [INACTIVE]");
|
||||||
#endif
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,11 +276,7 @@ enum {
|
||||||
SUBSCRIBE, UNSUBSCRIBE, LIST, REMOVE_ALL
|
SUBSCRIBE, UNSUBSCRIBE, LIST, REMOVE_ALL
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HANDLE_SHOW_ALL
|
|
||||||
#define ACONNECT_OPTS "dior:t:elxa"
|
#define ACONNECT_OPTS "dior:t:elxa"
|
||||||
#else
|
|
||||||
#define ACONNECT_OPTS "dior:t:elx"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const struct option long_option[] = {
|
static const struct option long_option[] = {
|
||||||
{"disconnect", 0, NULL, 'd'},
|
{"disconnect", 0, NULL, 'd'},
|
||||||
|
@ -314,9 +287,7 @@ static const struct option long_option[] = {
|
||||||
{"exclusive", 0, NULL, 'e'},
|
{"exclusive", 0, NULL, 'e'},
|
||||||
{"list", 0, NULL, 'l'},
|
{"list", 0, NULL, 'l'},
|
||||||
{"removeall", 0, NULL, 'x'},
|
{"removeall", 0, NULL, 'x'},
|
||||||
#ifdef HANDLE_SHOW_ALL
|
|
||||||
{"all", 0, NULL, 'a'},
|
{"all", 0, NULL, 'a'},
|
||||||
#endif
|
|
||||||
{NULL, 0, NULL, 0},
|
{NULL, 0, NULL, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -370,12 +341,10 @@ int main(int argc, char **argv)
|
||||||
case 'x':
|
case 'x':
|
||||||
command = REMOVE_ALL;
|
command = REMOVE_ALL;
|
||||||
break;
|
break;
|
||||||
#ifdef HANDLE_SHOW_ALL
|
|
||||||
case 'a':
|
case 'a':
|
||||||
command = LIST;
|
command = LIST;
|
||||||
show_all = 1;
|
show_all = 1;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -30,9 +30,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
#include <alsa/ump_msg.h>
|
#include <alsa/ump_msg.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 31.25 kbaud, one start bit, eight data bits, two stop bits.
|
* 31.25 kbaud, one start bit, eight data bits, two stop bits.
|
||||||
|
@ -78,9 +76,7 @@ static int file_offset; /* current offset in input file */
|
||||||
static int num_tracks;
|
static int num_tracks;
|
||||||
static struct track *tracks;
|
static struct track *tracks;
|
||||||
static int smpte_timing;
|
static int smpte_timing;
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
static int ump_mode;
|
static int ump_mode;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* prints an error message to stderr */
|
/* prints an error message to stderr */
|
||||||
static void errormsg(const char *msg, ...)
|
static void errormsg(const char *msg, ...)
|
||||||
|
@ -685,7 +681,6 @@ static int fill_legacy_event(struct event* event, snd_seq_event_t *ev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
static unsigned char to_ump_status(unsigned char ev_type)
|
static unsigned char to_ump_status(unsigned char ev_type)
|
||||||
{
|
{
|
||||||
switch (ev_type) {
|
switch (ev_type) {
|
||||||
|
@ -762,13 +757,10 @@ static int fill_ump_event(struct event* event, snd_seq_ump_event_t *ump_ev,
|
||||||
snd_seq_ev_set_ump_data(ump_ev, &ump, sizeof(ump));
|
snd_seq_ev_set_ump_data(ump_ev, &ump, sizeof(ump));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION */
|
|
||||||
|
|
||||||
static void play_midi(void)
|
static void play_midi(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
snd_seq_ump_event_t ump_ev;
|
snd_seq_ump_event_t ump_ev;
|
||||||
#endif
|
|
||||||
snd_seq_event_t ev;
|
snd_seq_event_t ev;
|
||||||
int i, max_tick, err;
|
int i, max_tick, err;
|
||||||
|
|
||||||
|
@ -830,7 +822,7 @@ static void play_midi(void)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
if (ump_mode) {
|
if (ump_mode) {
|
||||||
err = fill_ump_event(event, &ump_ev, &ev);
|
err = fill_ump_event(event, &ump_ev, &ev);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -839,7 +831,6 @@ static void play_midi(void)
|
||||||
check_snd("output event", err);
|
check_snd("output event", err);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* this blocks when the output pool has been filled */
|
/* this blocks when the output pool has been filled */
|
||||||
err = snd_seq_event_output(seq, &ev);
|
err = snd_seq_event_output(seq, &ev);
|
||||||
|
@ -957,9 +948,7 @@ static void usage(const char *argv0)
|
||||||
"-V, --version print current version\n"
|
"-V, --version print current version\n"
|
||||||
"-l, --list list all possible output ports\n"
|
"-l, --list list all possible output ports\n"
|
||||||
"-p, --port=client:port,... set port(s) to play to\n"
|
"-p, --port=client:port,... set port(s) to play to\n"
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
"-u, --ump=version UMP output (only version=1 is supported)\n"
|
"-u, --ump=version UMP output (only version=1 is supported)\n"
|
||||||
#endif
|
|
||||||
"-d, --delay=seconds delay after song ends\n",
|
"-d, --delay=seconds delay after song ends\n",
|
||||||
argv0);
|
argv0);
|
||||||
}
|
}
|
||||||
|
@ -969,12 +958,7 @@ static void version(void)
|
||||||
puts("aplaymidi version " SND_UTIL_VERSION_STR);
|
puts("aplaymidi version " SND_UTIL_VERSION_STR);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
#define OPTIONS "hVlp:d:u:"
|
#define OPTIONS "hVlp:d:u:"
|
||||||
#else
|
|
||||||
#define OPTIONS "hVlp:d:"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -984,9 +968,7 @@ int main(int argc, char *argv[])
|
||||||
{"version", 0, NULL, 'V'},
|
{"version", 0, NULL, 'V'},
|
||||||
{"list", 0, NULL, 'l'},
|
{"list", 0, NULL, 'l'},
|
||||||
{"port", 1, NULL, 'p'},
|
{"port", 1, NULL, 'p'},
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
{"ump", 1, NULL, 'u'},
|
{"ump", 1, NULL, 'u'},
|
||||||
#endif
|
|
||||||
{"delay", 1, NULL, 'd'},
|
{"delay", 1, NULL, 'd'},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
@ -1013,15 +995,11 @@ int main(int argc, char *argv[])
|
||||||
case 'd':
|
case 'd':
|
||||||
end_delay = atoi(optarg);
|
end_delay = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
case 'u':
|
case 'u':
|
||||||
if (strcmp(optarg, "1")) {
|
ump_mode = atoi(optarg);
|
||||||
errormsg("Only MIDI 1.0 is supported");
|
if (ump_mode < 0 || ump_mode > 1)
|
||||||
return 1;
|
fatal("Only MIDI 1.0 is supported");
|
||||||
}
|
|
||||||
ump_mode = 1;
|
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1029,13 +1007,11 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
if (ump_mode) {
|
if (ump_mode) {
|
||||||
int err;
|
int err;
|
||||||
err = snd_seq_set_client_midi_version(seq, SND_SEQ_CLIENT_UMP_MIDI_1_0);
|
err = snd_seq_set_client_midi_version(seq, SND_SEQ_CLIENT_UMP_MIDI_1_0);
|
||||||
check_snd("set midi version", err);
|
check_snd("set midi version", err);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (do_list) {
|
if (do_list) {
|
||||||
list_ports();
|
list_ports();
|
||||||
|
|
|
@ -29,9 +29,7 @@
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
#include <alsa/ump_msg.h>
|
#include <alsa/ump_msg.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VIEW_RAW, VIEW_NORMALIZED, VIEW_PERCENT
|
VIEW_RAW, VIEW_NORMALIZED, VIEW_PERCENT
|
||||||
|
@ -41,11 +39,7 @@ static snd_seq_t *seq;
|
||||||
static int port_count;
|
static int port_count;
|
||||||
static snd_seq_addr_t *ports;
|
static snd_seq_addr_t *ports;
|
||||||
static volatile sig_atomic_t stop = 0;
|
static volatile sig_atomic_t stop = 0;
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
static int ump_version;
|
static int ump_version;
|
||||||
#else
|
|
||||||
#define ump_version 0
|
|
||||||
#endif
|
|
||||||
static int view_mode = VIEW_RAW;
|
static int view_mode = VIEW_RAW;
|
||||||
|
|
||||||
/* prints an error message to stderr, and dies */
|
/* prints an error message to stderr, and dies */
|
||||||
|
@ -368,7 +362,6 @@ static void dump_event(const snd_seq_event_t *ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
static int group_number(unsigned char c)
|
static int group_number(unsigned char c)
|
||||||
{
|
{
|
||||||
if (view_mode != VIEW_RAW)
|
if (view_mode != VIEW_RAW)
|
||||||
|
@ -442,7 +435,7 @@ static const char *midi2_velocity(unsigned int v)
|
||||||
snprintf(tmp, sizeof(tmp), "%.2f",
|
snprintf(tmp, sizeof(tmp), "%.2f",
|
||||||
((double)v * 64.0) / 0x8000);
|
((double)v * 64.0) / 0x8000);
|
||||||
else
|
else
|
||||||
snprintf(tmp, sizeof(tmp), ".2%f",
|
snprintf(tmp, sizeof(tmp), "%.2f",
|
||||||
((double)(v - 0x8000) * 63.0) / 0x7fff + 64.0);
|
((double)(v - 0x8000) * 63.0) / 0x7fff + 64.0);
|
||||||
return tmp;
|
return tmp;
|
||||||
} else if (view_mode == VIEW_PERCENT) {
|
} else if (view_mode == VIEW_PERCENT) {
|
||||||
|
@ -680,6 +673,7 @@ static void dump_ump_sysex_event(const unsigned int *ump)
|
||||||
int i, length;
|
int i, length;
|
||||||
|
|
||||||
printf("Group %2d, ", group_number(snd_ump_msg_group(ump)));
|
printf("Group %2d, ", group_number(snd_ump_msg_group(ump)));
|
||||||
|
printf("SysEx ");
|
||||||
switch (snd_ump_sysex_msg_status(ump)) {
|
switch (snd_ump_sysex_msg_status(ump)) {
|
||||||
case SND_UMP_SYSEX_STATUS_SINGLE:
|
case SND_UMP_SYSEX_STATUS_SINGLE:
|
||||||
printf("Single ");
|
printf("Single ");
|
||||||
|
@ -986,7 +980,6 @@ static void dump_ump_event(const snd_seq_ump_event_t *ev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION */
|
|
||||||
|
|
||||||
static void list_ports(void)
|
static void list_ports(void)
|
||||||
{
|
{
|
||||||
|
@ -1029,10 +1022,8 @@ static void help(const char *argv0)
|
||||||
" -N,--normalized-view show normalized values\n"
|
" -N,--normalized-view show normalized values\n"
|
||||||
" -P,--percent-view show percent values\n"
|
" -P,--percent-view show percent values\n"
|
||||||
" -R,--raw-view show raw values (default)\n"
|
" -R,--raw-view show raw values (default)\n"
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
" -u,--ump=version set client MIDI version (0=legacy, 1= UMP MIDI 1.0, 2=UMP MIDI2.0)\n"
|
" -u,--ump=version set client MIDI version (0=legacy, 1= UMP MIDI 1.0, 2=UMP MIDI2.0)\n"
|
||||||
" -r,--raw do not convert UMP and legacy events\n"
|
" -r,--raw do not convert UMP and legacy events\n"
|
||||||
#endif
|
|
||||||
" -p,--port=client:port,... source port(s)\n",
|
" -p,--port=client:port,... source port(s)\n",
|
||||||
argv0);
|
argv0);
|
||||||
}
|
}
|
||||||
|
@ -1049,11 +1040,7 @@ static void sighandler(int sig ATTRIBUTE_UNUSED)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
static const char short_options[] = "hVlp:NPR"
|
static const char short_options[] = "hVlp:NPRu:r";
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
"u:r"
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{"help", 0, NULL, 'h'},
|
{"help", 0, NULL, 'h'},
|
||||||
{"version", 0, NULL, 'V'},
|
{"version", 0, NULL, 'V'},
|
||||||
|
@ -1062,10 +1049,8 @@ int main(int argc, char *argv[])
|
||||||
{"normalized-view", 0, NULL, 'N'},
|
{"normalized-view", 0, NULL, 'N'},
|
||||||
{"percent-view", 0, NULL, 'P'},
|
{"percent-view", 0, NULL, 'P'},
|
||||||
{"raw-view", 0, NULL, 'R'},
|
{"raw-view", 0, NULL, 'R'},
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
{"ump", 1, NULL, 'u'},
|
{"ump", 1, NULL, 'u'},
|
||||||
{"raw", 0, NULL, 'r'},
|
{"raw", 0, NULL, 'r'},
|
||||||
#endif
|
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1100,15 +1085,15 @@ int main(int argc, char *argv[])
|
||||||
case 'N':
|
case 'N':
|
||||||
view_mode = VIEW_NORMALIZED;
|
view_mode = VIEW_NORMALIZED;
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
case 'u':
|
case 'u':
|
||||||
ump_version = atoi(optarg);
|
ump_version = atoi(optarg);
|
||||||
|
if (ump_version < 0 || ump_version > 2)
|
||||||
|
fatal("Invalid UMP version %d", ump_version);
|
||||||
snd_seq_set_client_midi_version(seq, ump_version);
|
snd_seq_set_client_midi_version(seq, ump_version);
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
snd_seq_set_client_ump_conversion(seq, 0);
|
snd_seq_set_client_ump_conversion(seq, 0);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
help(argv[0]);
|
help(argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1150,7 +1135,6 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
snd_seq_event_t *event;
|
snd_seq_event_t *event;
|
||||||
#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
|
|
||||||
snd_seq_ump_event_t *ump_ev;
|
snd_seq_ump_event_t *ump_ev;
|
||||||
if (ump_version > 0) {
|
if (ump_version > 0) {
|
||||||
err = snd_seq_ump_event_input(seq, &ump_ev);
|
err = snd_seq_ump_event_input(seq, &ump_ev);
|
||||||
|
@ -1160,7 +1144,6 @@ int main(int argc, char *argv[])
|
||||||
dump_ump_event(ump_ev);
|
dump_ump_event(ump_ev);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
err = snd_seq_event_input(seq, &event);
|
err = snd_seq_event_input(seq, &event);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
|
@ -14,41 +14,48 @@ It can also send any other MIDI commands.
|
||||||
Messages to be send can be given in the last argument as hex encoded byte string or can be read from raw binary file.
|
Messages to be send can be given in the last argument as hex encoded byte string or can be read from raw binary file.
|
||||||
When sending several SysEx messages at once there is a delay of 1ms after each message as deafult and can be set to different value with option \-i.
|
When sending several SysEx messages at once there is a delay of 1ms after each message as deafult and can be set to different value with option \-i.
|
||||||
|
|
||||||
.SH OPTIONS
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\-h
|
|
||||||
Prints a list of options.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\-V
|
|
||||||
Prints the current version.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\-l
|
|
||||||
Prints a list of possible output ports.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\-v
|
|
||||||
Prints number of bytes actually sent
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\-p
|
|
||||||
Target port by number or name
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\-s
|
|
||||||
Send raw binary data from given file name
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\-i
|
|
||||||
Interval between SysEx messages in miliseconds
|
|
||||||
|
|
||||||
|
|
||||||
A client can be specified by its number, its name, or a prefix of its
|
A client can be specified by its number, its name, or a prefix of its
|
||||||
name. A port is specified by its number; for port 0 of a client, the
|
name. A port is specified by its number; for port 0 of a client, the
|
||||||
":0" part of the port specification can be omitted.
|
":0" part of the port specification can be omitted.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\-h, \-\-help
|
||||||
|
Prints a list of options.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\-V, \-\-version
|
||||||
|
Prints the current version.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\-l, \-\-list
|
||||||
|
Prints a list of possible output ports.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\-v, \-\-verbose
|
||||||
|
Prints number of bytes actually sent
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\-p, -\-port=client:port
|
||||||
|
Target port by number or name
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\-s, \-\-file=filename
|
||||||
|
Send raw binary data from given file name
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\-i, \-\-interval=msec
|
||||||
|
Interval between SysEx messages in miliseconds
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\-u, \-\-ump=version
|
||||||
|
Specify the MIDI version. 0 for the legacy MIDI 1.0 (default),
|
||||||
|
1 for UMP MIDI 1.0 protocol and 2 for UMP MIDI 2.0 protocol.
|
||||||
|
|
||||||
|
When UMP MIDI 1.0 or MIDI 2.0 protocol is specified, \fBaseqsend\fP
|
||||||
|
reads the input as raw UMP packets, 4 each byte in big endian.
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
|
|
||||||
aseqsend -p 128:0 "F0 41 10 00 00 64 12 18 00 21 06 59 41 59 4E F7"
|
aseqsend -p 128:0 "F0 41 10 00 00 64 12 18 00 21 06 59 41 59 4E F7"
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
|
#include <alsa/ump_msg.h>
|
||||||
|
|
||||||
typedef unsigned char mbyte_t;
|
typedef unsigned char mbyte_t;
|
||||||
|
|
||||||
|
@ -43,6 +44,7 @@ static char *send_hex;
|
||||||
static mbyte_t *send_data;
|
static mbyte_t *send_data;
|
||||||
static snd_seq_addr_t addr;
|
static snd_seq_addr_t addr;
|
||||||
static int send_data_length;
|
static int send_data_length;
|
||||||
|
static int ump_version;
|
||||||
|
|
||||||
static void error(const char *format, ...)
|
static void error(const char *format, ...)
|
||||||
{
|
{
|
||||||
|
@ -320,6 +322,32 @@ static void send_midi_msg(snd_seq_event_type_t type, mbyte_t *data, int len)
|
||||||
snd_seq_drain_output(seq);
|
snd_seq_drain_output(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int send_ump(const unsigned char *data)
|
||||||
|
{
|
||||||
|
static int ump_len = 0, offset = 0;
|
||||||
|
unsigned int ump[4];
|
||||||
|
snd_seq_ump_event_t ev;
|
||||||
|
|
||||||
|
ump[offset] = (data[0] << 24) | (data[1] << 16) |
|
||||||
|
(data[2] << 8) | data[3];
|
||||||
|
if (!offset)
|
||||||
|
ump_len = snd_ump_packet_length(snd_ump_msg_type(ump));
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
if (offset < ump_len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snd_seq_ump_ev_clear(&ev);
|
||||||
|
snd_seq_ev_set_source(&ev, 0);
|
||||||
|
snd_seq_ev_set_dest(&ev, addr.client, addr.port);
|
||||||
|
snd_seq_ev_set_direct(&ev);
|
||||||
|
snd_seq_ev_set_ump_data(&ev, ump, ump_len * 4);
|
||||||
|
snd_seq_ump_event_output(seq, &ev);
|
||||||
|
snd_seq_drain_output(seq);
|
||||||
|
offset = 0;
|
||||||
|
return ump_len * 4;
|
||||||
|
}
|
||||||
|
|
||||||
static int msg_byte_in_range(mbyte_t *data, mbyte_t len)
|
static int msg_byte_in_range(mbyte_t *data, mbyte_t len)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
|
@ -334,6 +362,17 @@ static int msg_byte_in_range(mbyte_t *data, mbyte_t len)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
static const struct option long_options[] = {
|
||||||
|
{"help", 0, NULL, 'h'},
|
||||||
|
{"version", 0, NULL, 'V'},
|
||||||
|
{"verbose", 0, NULL, 'v'},
|
||||||
|
{"list", 0, NULL, 'l'},
|
||||||
|
{"port", 1, NULL, 'p'},
|
||||||
|
{"file", 1, NULL, 's'},
|
||||||
|
{"interval", 1, NULL, 'i'},
|
||||||
|
{"ump", 1, NULL, 'u'},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
char c = 0;
|
char c = 0;
|
||||||
char do_send_file = 0;
|
char do_send_file = 0;
|
||||||
char do_port_list = 0;
|
char do_port_list = 0;
|
||||||
|
@ -342,7 +381,7 @@ int main(int argc, char *argv[])
|
||||||
int sent_data_c;
|
int sent_data_c;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "hi:Vvlp:s:")) != -1) {
|
while ((c = getopt_long(argc, argv, "hi:Vvlp:s:u:", long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
usage();
|
usage();
|
||||||
|
@ -366,6 +405,9 @@ int main(int argc, char *argv[])
|
||||||
case 'i':
|
case 'i':
|
||||||
sysex_interval = atoi(optarg) * 1000; //ms--->us
|
sysex_interval = atoi(optarg) * 1000; //ms--->us
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
ump_version = atoi(optarg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
error("Try 'aseqsend -h' for more information.");
|
error("Try 'aseqsend -h' for more information.");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -401,7 +443,11 @@ int main(int argc, char *argv[])
|
||||||
if (!send_data)
|
if (!send_data)
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
|
if (ump_version && (send_data_length % 4) != 0)
|
||||||
|
fatal("UMP data must be aligned to 4 bytes");
|
||||||
|
|
||||||
init_seq();
|
init_seq();
|
||||||
|
snd_seq_set_client_midi_version(seq, ump_version);
|
||||||
create_port();
|
create_port();
|
||||||
|
|
||||||
if (snd_seq_parse_address(seq, &addr, port_name) < 0) {
|
if (snd_seq_parse_address(seq, &addr, port_name) < 0) {
|
||||||
|
@ -414,6 +460,12 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
while (k < send_data_length) {
|
while (k < send_data_length) {
|
||||||
|
|
||||||
|
if (ump_version) {
|
||||||
|
sent_data_c += send_ump(send_data + k);
|
||||||
|
k += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (send_data[k] == 0xF0) {
|
if (send_data[k] == 0xF0) {
|
||||||
|
|
||||||
int c1 = k;
|
int c1 = k;
|
||||||
|
|
|
@ -921,6 +921,172 @@ static int pre_process_arrays(struct tplg_pre_processor *tplg_pp, snd_config_t *
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pre_process_subtree_copy(struct tplg_pre_processor *tplg_pp, snd_config_t *curr,
|
||||||
|
snd_config_t *top)
|
||||||
|
{
|
||||||
|
snd_config_iterator_t i, next;
|
||||||
|
snd_config_t *subtrees;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = snd_config_search(curr, "SubTreeCopy", &subtrees);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snd_config_for_each(i, next, subtrees) {
|
||||||
|
snd_config_t *n, *source_cfg, *target_cfg, *type_cfg;
|
||||||
|
snd_config_t *source_tree, *target_tree, *tmp, *subtree_cfg;
|
||||||
|
const char *id, *source_id;
|
||||||
|
const char *type = NULL;
|
||||||
|
const char *target_id = NULL;
|
||||||
|
bool override = false;
|
||||||
|
|
||||||
|
n = snd_config_iterator_entry(i);
|
||||||
|
ret = snd_config_get_id(n, &id);
|
||||||
|
if (ret < 0) {
|
||||||
|
SNDERR("Failed to get ID for subtree copy\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the type of copy ex: override/extend if set, by default override is false */
|
||||||
|
ret = snd_config_search(n, "type", &type_cfg);
|
||||||
|
if (ret >= 0) {
|
||||||
|
ret = snd_config_get_string(type_cfg, &type);
|
||||||
|
if (ret >= 0) {
|
||||||
|
if (strcmp(type, "override") && strcmp(type, "extend")) {
|
||||||
|
SNDERR("Invalid value for sub tree copy type %s\n", type);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(type, "override"))
|
||||||
|
override = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_config_search(n, "source", &source_cfg);
|
||||||
|
if (ret < 0) {
|
||||||
|
SNDERR("failed to get source config for subtree %s\n", id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the target node is not set, the subtree will be copied to current node */
|
||||||
|
ret = snd_config_search(n, "target", &target_cfg);
|
||||||
|
if (ret >= 0) {
|
||||||
|
snd_config_t *temp_target;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
ret = snd_config_get_string(target_cfg, &target_id);
|
||||||
|
if (ret < 0) {
|
||||||
|
SNDERR("Invalid target id for subtree %s\n", id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create a temporary node with target_id and merge with top to avoid
|
||||||
|
* failure in case the target node ID doesn't exist already
|
||||||
|
*/
|
||||||
|
s = tplg_snprintf("%s {}", target_id);
|
||||||
|
if (!s)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = snd_config_load_string(&temp_target, s, 0);
|
||||||
|
free(s);
|
||||||
|
if (ret < 0) {
|
||||||
|
SNDERR("Cannot create temp node with target id %s\n", target_id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_config_merge(top, temp_target, false);
|
||||||
|
if (ret < 0) {
|
||||||
|
SNDERR("Cannot merge temp node with target id %s\n", target_id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_config_search(top, target_id, &target_tree);
|
||||||
|
if (ret < 0) {
|
||||||
|
SNDERR("failed to get target tree %s\n", target_id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
target_tree = curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the source tree node */
|
||||||
|
ret = snd_config_get_string(source_cfg, &source_id);
|
||||||
|
if (ret < 0) {
|
||||||
|
SNDERR("Invalid source node id for subtree %s\n", id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_config_search(top, source_id, &source_tree);
|
||||||
|
if (ret < 0) {
|
||||||
|
SNDERR("failed to get source tree %s\n", source_id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the subtree to be merged */
|
||||||
|
ret = snd_config_search(n, "tree", &subtree_cfg);
|
||||||
|
if (ret < 0)
|
||||||
|
subtree_cfg = NULL;
|
||||||
|
|
||||||
|
/* make a temp copy of the source tree */
|
||||||
|
ret = snd_config_copy(&tmp, source_tree);
|
||||||
|
if (ret < 0) {
|
||||||
|
SNDERR("failed to copy source tree for subtreecopy %s\n", id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* merge the current block with the source tree */
|
||||||
|
ret = snd_config_merge(tmp, subtree_cfg, override);
|
||||||
|
if (ret < 0) {
|
||||||
|
snd_config_delete(tmp);
|
||||||
|
SNDERR("Failed to merge source tree w/ subtree %s\n", id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* merge the merged block to the target tree */
|
||||||
|
ret = snd_config_merge(target_tree, tmp, override);
|
||||||
|
if (ret < 0) {
|
||||||
|
snd_config_delete(tmp);
|
||||||
|
SNDERR("Failed to merge subtree %s w/ target\n", id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all subtree copies have been processed, remove the node */
|
||||||
|
snd_config_delete(subtrees);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pre_process_subtree_copies(struct tplg_pre_processor *tplg_pp, snd_config_t *top,
|
||||||
|
snd_config_t *curr)
|
||||||
|
{
|
||||||
|
snd_config_iterator_t i, next;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (snd_config_get_type(curr) != SND_CONFIG_TYPE_COMPOUND)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* process subtreecopies at this node */
|
||||||
|
ret = pre_process_subtree_copy(tplg_pp, curr, top);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* process subtreecopies at all child nodes */
|
||||||
|
snd_config_for_each(i, next, curr) {
|
||||||
|
snd_config_t *n;
|
||||||
|
|
||||||
|
n = snd_config_iterator_entry(i);
|
||||||
|
|
||||||
|
/* process subtreecopies at this node */
|
||||||
|
ret = pre_process_subtree_copies(tplg_pp, top, n);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* version < 1.2.6 */
|
#endif /* version < 1.2.6 */
|
||||||
|
|
||||||
int pre_process(struct tplg_pre_processor *tplg_pp, char *config, size_t config_size,
|
int pre_process(struct tplg_pre_processor *tplg_pp, char *config, size_t config_size,
|
||||||
|
@ -980,6 +1146,12 @@ int pre_process(struct tplg_pre_processor *tplg_pp, char *config, size_t config_
|
||||||
fprintf(stderr, "Failed to process object arrays in input config\n");
|
fprintf(stderr, "Failed to process object arrays in input config\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = pre_process_subtree_copies(tplg_pp, tplg_pp->input_cfg, tplg_pp->input_cfg);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("Failed to process subtree copies in input config\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
err = pre_process_config(tplg_pp, tplg_pp->input_cfg);
|
err = pre_process_config(tplg_pp, tplg_pp->input_cfg);
|
||||||
|
|
Loading…
Reference in a new issue