]> git.alsa-project.org Git - alsa-utils.git/commitdiff
split interleaved files in arecord when reaching 2GB
authorTakashi Iwai <tiwai@suse.de>
Tue, 6 Dec 2005 11:25:47 +0000 (11:25 +0000)
committerTakashi Iwai <tiwai@suse.de>
Tue, 6 Dec 2005 11:25:47 +0000 (11:25 +0000)
From: Dirk Jagdmann <doj@cubic.org>

This patch will split files in chunks of aprox. 2GB in the interleaved
recording mode of arecord. This is meant to overcome the 2GB filesize
limit of .wav files, which is easily reached when recording multiple
channels.

aplay/aplay.1
aplay/aplay.c

index 394bc9a2438e240954ac61e811f137281f36691b..a518a6e92414a1daac62f92626f2029361e1c7fd 100644 (file)
@@ -10,7 +10,8 @@ soundcard driver
 .SH DESCRIPTION
 \fBarecord\fP is a command-line soundfile recorder for the ALSA soundcard
 driver. It supports several file formats and multiple soundcards with
-multiple devices. 
+multiple devices. If recording with interleaved mode samples the file is
+automatically split before the 2GB filesize.
 
 \fBaplay\fP is much the same, only it plays instead of recording. For
 supported soundfile formats, the sampling rate, bit depth, and so
index 572e48e788b804aa7fac0e81124fd11101a47251..1818d4363b662ee1d066b93827940e2e2118ca7e 100644 (file)
@@ -124,11 +124,12 @@ struct fmt_capture {
        void (*start) (int fd, size_t count);
        void (*end) (int fd);
        char *what;
+       long long max_filesize;
 } fmt_rec_table[] = {
-       {       NULL,           end_raw,        N_("raw data")  },
-       {       begin_voc,      end_voc,        N_("VOC")       },
-       {       begin_wave,     end_wave,       N_("WAVE")      },
-       {       begin_au,       end_au,         N_("Sparc Audio")}
+       {       NULL,           end_raw,        N_("raw data"),         LLONG_MAX },
+       {       begin_voc,      end_voc,        N_("VOC"),              16000000 },
+       {       begin_wave,     end_wave,       N_("WAVE"),             2000000000 },
+       {       begin_au,       end_au,         N_("Sparc Audio"),      LLONG_MAX }
 };
 
 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
@@ -1985,33 +1986,6 @@ void playback_go(int fd, size_t loaded, off64_t count, int rtype, char *name)
        snd_pcm_drain(handle);
 }
 
-/* capturing raw data, this proc handels WAVE files and .VOCs (as one block) */
-
-void capture_go(int fd, off64_t count, int rtype, char *name)
-{
-       size_t c;
-       off64_t cur;
-       ssize_t r, err;
-
-       header(rtype, name);
-       set_params();
-
-       do {
-               for (cur = count; cur > 0; cur -= r) {
-                       c = (cur <= chunk_bytes) ? cur : chunk_bytes;
-                       c = c * 8 / bits_per_frame;
-                       if ((size_t)(r = pcm_read(audiobuf, c)) != c)
-                               break;
-                       r = r * bits_per_frame / 8;
-                       if ((err = write(fd, audiobuf, r)) != r) {
-                               perror(name);
-                               exit(EXIT_FAILURE);
-                       }
-                       if (err > 0)
-                               fdcount += err;
-               }
-       } while (rtype == FORMAT_RAW && !timelimit);
-}
 
 /*
  *  let's play or capture it (capture_type says VOC/WAVE/raw)
@@ -2072,20 +2046,15 @@ static void playback(char *name)
                close(fd);
 }
 
-static void capture(char *name)
+static void capture(char *name_)
 {
-       pbrec_count = LLONG_MAX;
-       if (!name || !strcmp(name, "-")) {
-               fd = fileno(stdout);
-               name = "stdout";
-       } else {
-               remove(name);
-               if ((fd = open64(name, O_WRONLY | O_CREAT, 0644)) == -1) {
-                       perror(name);
-                       exit(EXIT_FAILURE);
-               }
-       }
-       fdcount = 0;
+       int tostdout=0;         /* boolean which describes output stream */
+       int filecount=0;        /* number of files written */
+       char *name=name_;       /* current filename */
+       char namebuf[PATH_MAX+1];
+       off64_t cur;            /* number of bytes to capture */
+
+       /* get number of bytes to capture */
        pbrec_count = calc_count();
        /* WAVE-file should be even (I'm not sure), but wasting one byte
           isn't a problem (this can only be in 8 bit mono) */
@@ -2095,10 +2064,107 @@ static void capture(char *name)
                pbrec_count -= pbrec_count % 2;
        if (pbrec_count == 0)
                pbrec_count -= 2;
-       if (fmt_rec_table[file_type].start)
-               fmt_rec_table[file_type].start(fd, pbrec_count);
-       capture_go(fd, pbrec_count, file_type, name);
-       fmt_rec_table[file_type].end(fd);
+
+       cur = pbrec_count;
+
+       /* display verbose output to console */
+       header(file_type, name);
+
+       /* setup sound hardware */
+       set_params();
+
+       /* write to stdout? */
+       if (!name || !strcmp(name, "-")) {
+               fd = fileno(stdout);
+               name = "stdout";
+               tostdout=1;
+               fdcount = 0;
+       }
+
+       do {
+               /* open a file to write */
+               if(!tostdout) {
+
+                       /* upon the second file we start the numbering scheme */
+                       if(filecount)
+                       {
+                               /* get a copy of the original filename */
+                               char *s;
+                               char buf[PATH_MAX+1];
+                               strncpy(buf, name_, sizeof(buf));
+
+                               /* separate extension from filename */
+                               s=buf+strlen(buf);
+                               while(s>buf && *s!='.' && *s!='/')
+                                       --s;
+                               if(*s=='.')
+                                       *s++=0;
+                               else if(*s=='/')
+                                       s=buf+strlen(buf);
+
+                               /* upon first jump to this if block rename the first file */
+                               if(filecount==1) {
+                                       if(*s)
+                                               snprintf(namebuf, sizeof(namebuf), "%s-01.%s", buf, s);
+                                       else
+                                               snprintf(namebuf, sizeof(namebuf), "%s-01", buf);
+                                       remove(namebuf);
+                                       rename(name, namebuf);
+                                       filecount=2;
+                               }
+
+                               /* name of the current file */
+                               if(*s)
+                                       snprintf(namebuf, sizeof(namebuf), "%s-%02i.%s", buf, filecount, s);
+                               else
+                                       snprintf(namebuf, sizeof(namebuf), "%s-%02i", buf, filecount);
+                               name=namebuf;
+
+                       }
+
+                       /* open a new file */
+                       remove(name);
+                       if ((fd = open64(name, O_WRONLY | O_CREAT, 0644)) == -1) {
+                               perror(name);
+                               exit(EXIT_FAILURE);
+                       }
+                       fdcount = 0;
+                       filecount++;
+               }
+
+               /* setup sample header */
+               if (fmt_rec_table[file_type].start)
+                       fmt_rec_table[file_type].start(fd, pbrec_count);
+
+               /* capture */
+               do {
+                       ssize_t r=0;
+                       for (; cur > 0 && fdcount<fmt_rec_table[file_type].max_filesize; cur -= r) {
+                               ssize_t err;
+                               size_t c = (cur <= chunk_bytes) ? cur : chunk_bytes;
+                               c = c * 8 / bits_per_frame;
+                               if ((size_t)(r = pcm_read(audiobuf, c)) != c)
+                                       break;
+                               r = r * bits_per_frame / 8;
+                               if ((err = write(fd, audiobuf, r)) != r) {
+                                       perror(name);
+                                       exit(EXIT_FAILURE);
+                               }
+                               if (err > 0)
+                                       fdcount += err;
+                       }
+                       /* exit conditions:
+                          1) format_raw and a timelimit
+                          2) all requested samples/bytes have been captured (cur>0)
+                          3) filesize threshold was reached (fdcount<wrthreshold)
+                       */
+               } while (file_type == FORMAT_RAW && !timelimit && cur>0 && fdcount<fmt_rec_table[file_type].max_filesize);
+
+               /* finish sample container */
+               fmt_rec_table[file_type].end(fd);
+
+               /* repeat the loop when format is raw without timelimit or filesize threshold was reached */
+       } while((file_type == FORMAT_RAW && !timelimit) || fdcount>=fmt_rec_table[file_type].max_filesize);
 }
 
 void playbackv_go(int* fds, unsigned int channels, size_t loaded, off64_t count, int rtype, char **names)