]> git.alsa-project.org Git - alsa-utils.git/commitdiff
arecordmidi2: Add --profile option
authorTakashi Iwai <tiwai@suse.de>
Tue, 9 Jul 2024 06:08:06 +0000 (08:08 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 9 Jul 2024 06:09:45 +0000 (08:09 +0200)
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 <tiwai@suse.de>
seq/aplaymidi2/arecordmidi2.1
seq/aplaymidi2/arecordmidi2.c

index 3af849b3bdba746adac100d05f5633a9319a627f..42e411ff6877df74d02edcb82c880d1a8f44bb40 100644 (file)
@@ -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
index 539253af185d8d75cf0969f3ccb55a5e84b8758b..c4a841c44376712688cbfe832b5da3a137eaa9bc 100644 (file)
@@ -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)
@@ -337,6 +338,47 @@ 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)
 {
@@ -344,7 +386,7 @@ static void write_file_header(FILE *file)
        fwrite("SMF2CLIP", 1, 8, file);
 
        /* clip configuration header */
-       /* FIXME: add profiles */
+       write_profiles(file);
 
        /* first DCS */
        write_dcs(file, 0);
@@ -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);
 }
 
@@ -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'},
@@ -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}
        };
 
@@ -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;