Skip to content

Commit

Permalink
arecordmidi2: Add --profile option
Browse files Browse the repository at this point in the history
Allow to add arbitrary profile UMP data to be put into the
configuration of the recorded stream via --profile option.
The file must contain valid UMP data encoded in big-endian.

Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
tiwai committed Jul 9, 2024
1 parent f0df4b4 commit 274f1b9
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 3 deletions.
6 changes: 6 additions & 0 deletions seq/aplaymidi2/arecordmidi2.1
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ discarded.
.I \-s,\-\-silent
Don't print messages to stdout.

.TP
.I \-P,\-\-profile=file
Read the UMP data from the given file and put them into the
configuration section of the recorded output.
The file must contain only valid UMP data encoded in big-endian.

.SH SEE ALSO
arecordmidi(1)
.br
Expand Down
53 changes: 50 additions & 3 deletions seq/aplaymidi2/arecordmidi2.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static int ts_num = 4; /* time signature: numerator */
static int ts_div = 4; /* time signature: denominator */
static int last_tick;
static int silent;
static const char *profile_ump_file;

/* Parse a decimal number from a command line argument. */
static long arg_parse_decimal_num(const char *str, int *err)
Expand Down Expand Up @@ -337,14 +338,55 @@ static void record_event(FILE *file, const snd_seq_ump_event_t *ev)
write_ump(file, ev->ump);
}

/* read a UMP raw (big-endian) packet, return the packet length in words */
static int read_ump_raw(FILE *file, uint32_t *buf)
{
uint32_t v;
int i, num;

if (fread(buf, 4, 1, file) != 1)
return 0;
v = be32toh(v);
num = snd_ump_packet_length(snd_ump_msg_hdr_type(v));
for (i = 1; i < num; i++) {
if (fread(buf + i, 4, 1, file) != 1)
return 0;
}
return num;
}

/* read the profile UMP data and write to the configuration */
static void write_profiles(FILE *file)
{
FILE *fp;
uint32_t ump[4];
int len;

if (!profile_ump_file)
return;

fp = fopen(profile_ump_file, "rb");
if (!fp)
fatal("cannot open the profile '%s'", profile_ump_file);

while (!feof(fp)) {
len = read_ump_raw(fp, ump);
if (!len)
break;
fwrite(ump, 4, len, file);
}

fclose(fp);
}

/* write MIDI Clip file header and the configuration packets */
static void write_file_header(FILE *file)
{
/* header id */
fwrite("SMF2CLIP", 1, 8, file);

/* clip configuration header */
/* FIXME: add profiles */
write_profiles(file);

/* first DCS */
write_dcs(file, 0);
Expand Down Expand Up @@ -379,7 +421,8 @@ static void help(const char *argv0)
" -n,--num-events=events fixed number of events to record, then exit\n"
" -u,--ump=version UMP MIDI version (1 or 2)\n"
" -r,--interactive Interactive mode\n"
" -s,--silent don't print messages\n",
" -s,--silent don't print messages\n"
" -P,--profile=file configuration profile UMP\n",
argv0);
}

Expand All @@ -395,7 +438,7 @@ static void sighandler(int sig ATTRIBUTE_UNUSED)

int main(int argc, char *argv[])
{
static const char short_options[] = "hVp:b:t:n:u:rs";
static const char short_options[] = "hVp:b:t:n:u:rsP:";
static const struct option long_options[] = {
{"help", 0, NULL, 'h'},
{"version", 0, NULL, 'V'},
Expand All @@ -407,6 +450,7 @@ int main(int argc, char *argv[])
{"ump", 1, NULL, 'u'},
{"interactive", 0, NULL, 'r'},
{"silent", 0, NULL, 's'},
{"profile", 1, NULL, 'P'},
{0}
};

Expand Down Expand Up @@ -469,6 +513,9 @@ int main(int argc, char *argv[])
case 's':
silent = 1;
break;
case 'P':
profile_ump_file = optarg;
break;
default:
help(argv[0]);
return 1;
Expand Down

0 comments on commit 274f1b9

Please sign in to comment.