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)
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)
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) */
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)