aplay.c
来自「alsa-utils-1.0.14编译声卡驱动所需要的一些文件源码」· C语言 代码 · 共 2,374 行 · 第 1/5 页
C
2,374 行
write(fd, &rifflen, 4); if (lseek64(fd, length_seek, SEEK_SET) == length_seek) write(fd, &cd, sizeof(WaveChunkHeader)); if (fd != 1) close(fd);}static void end_au(int fd){ /* only close output */ AuHeader ah; off64_t length_seek; length_seek = (char *)&ah.data_size - (char *)&ah; ah.data_size = fdcount > 0xffffffff ? 0xffffffff : BE_INT(fdcount); if (lseek64(fd, length_seek, SEEK_SET) == length_seek) write(fd, &ah.data_size, sizeof(ah.data_size)); if (fd != 1) close(fd);}static void header(int rtype, char *name){ if (!quiet_mode) { if (! name) name = (stream == SND_PCM_STREAM_PLAYBACK) ? "stdout" : "stdin"; fprintf(stderr, "%s %s '%s' : ", (stream == SND_PCM_STREAM_PLAYBACK) ? _("Playing") : _("Recording"), gettext(fmt_rec_table[rtype].what), name); fprintf(stderr, "%s, ", snd_pcm_format_description(hwparams.format)); fprintf(stderr, _("Rate %d Hz, "), hwparams.rate); if (hwparams.channels == 1) fprintf(stderr, _("Mono")); else if (hwparams.channels == 2) fprintf(stderr, _("Stereo")); else fprintf(stderr, _("Channels %i"), hwparams.channels); fprintf(stderr, "\n"); }}/* playing raw data */void playback_go(int fd, size_t loaded, off64_t count, int rtype, char *name){ int l, r; off64_t written = 0; off64_t c; header(rtype, name); set_params(); while (loaded > chunk_bytes && written < count) { if (pcm_write(audiobuf + written, chunk_size) <= 0) return; written += chunk_bytes; loaded -= chunk_bytes; } if (written > 0 && loaded > 0) memmove(audiobuf, audiobuf + written, loaded); l = loaded; while (written < count) { do { c = count - written; if (c > chunk_bytes) c = chunk_bytes; c -= l; if (c == 0) break; r = safe_read(fd, audiobuf + l, c); if (r < 0) { perror(name); exit(EXIT_FAILURE); } fdcount += r; if (r == 0) break; l += r; } while (sleep_min == 0 && (size_t)l < chunk_bytes); l = l * 8 / bits_per_frame; r = pcm_write(audiobuf, l); if (r != l) break; r = r * bits_per_frame / 8; written += r; l = 0; } snd_pcm_drain(handle);}/* * let's play or capture it (capture_type says VOC/WAVE/raw) */static void playback(char *name){ int ofs; size_t dta; ssize_t dtawave; pbrec_count = LLONG_MAX; fdcount = 0; if (!name || !strcmp(name, "-")) { fd = fileno(stdin); name = "stdin"; } else { if ((fd = open64(name, O_RDONLY, 0)) == -1) { perror(name); exit(EXIT_FAILURE); } } /* read the file header */ dta = sizeof(AuHeader); if ((size_t)safe_read(fd, audiobuf, dta) != dta) { error(_("read error")); exit(EXIT_FAILURE); } if (test_au(fd, audiobuf) >= 0) { rhwparams.format = hwparams.format; pbrec_count = calc_count(); playback_go(fd, 0, pbrec_count, FORMAT_AU, name); goto __end; } dta = sizeof(VocHeader); if ((size_t)safe_read(fd, audiobuf + sizeof(AuHeader), dta - sizeof(AuHeader)) != dta - sizeof(AuHeader)) { error(_("read error")); exit(EXIT_FAILURE); } if ((ofs = test_vocfile(audiobuf)) >= 0) { pbrec_count = calc_count(); voc_play(fd, ofs, name); goto __end; } /* read bytes for WAVE-header */ if ((dtawave = test_wavefile(fd, audiobuf, dta)) >= 0) { pbrec_count = calc_count(); playback_go(fd, dtawave, pbrec_count, FORMAT_WAVE, name); } else { /* should be raw data */ init_raw_data(); pbrec_count = calc_count(); playback_go(fd, dta, pbrec_count, FORMAT_RAW, name); } __end: if (fd != 0) close(fd);}static int new_capture_file(char *name, char *namebuf, size_t namelen, int 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, namelen, "%s-01.%s", buf, s); else snprintf(namebuf, namelen, "%s-01", buf); remove(namebuf); rename(name, namebuf); filecount = 2; } /* name of the current file */ if (*s) snprintf(namebuf, namelen, "%s-%02i.%s", buf, filecount, s); else snprintf(namebuf, namelen, "%s-%02i", buf, filecount); return filecount;}static void capture(char *orig_name){ int tostdout=0; /* boolean which describes output stream */ int filecount=0; /* number of files written */ char *name = orig_name; /* current filename */ char namebuf[PATH_MAX+1]; off64_t count, rest; /* number of bytes to capture */ /* get number of bytes to capture */ count = calc_count(); if (count == 0) count = LLONG_MAX; /* 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) */ if (count < LLONG_MAX) count += count % 2; else count -= count % 2; /* 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; if (count > fmt_rec_table[file_type].max_filesize) count = fmt_rec_table[file_type].max_filesize; } do { /* open a file to write */ if(!tostdout) { /* upon the second file we start the numbering scheme */ if (filecount) { filecount = new_capture_file(orig_name, namebuf, sizeof(namebuf), filecount); name = namebuf; } /* open a new file */ remove(name); if ((fd = open64(name, O_WRONLY | O_CREAT, 0644)) == -1) { perror(name); exit(EXIT_FAILURE); } filecount++; } rest = count; if (rest > fmt_rec_table[file_type].max_filesize) rest = fmt_rec_table[file_type].max_filesize; /* setup sample header */ if (fmt_rec_table[file_type].start) fmt_rec_table[file_type].start(fd, rest); /* capture */ fdcount = 0; while (rest > 0) { size_t c = (rest <= (off64_t)chunk_bytes) ? (size_t)rest : chunk_bytes; size_t f = c * 8 / bits_per_frame; if (pcm_read(audiobuf, f) != f) break; if (write(fd, audiobuf, c) != c) { perror(name); exit(EXIT_FAILURE); } count -= c; rest -= c; fdcount += c; } /* finish sample container */ if (fmt_rec_table[file_type].end && !tostdout) { fmt_rec_table[file_type].end(fd); fd = -1; } /* repeat the loop when format is raw without timelimit or * requested counts of data are recorded */ } while ((file_type == FORMAT_RAW && !timelimit) || count > 0);}void playbackv_go(int* fds, unsigned int channels, size_t loaded, off64_t count, int rtype, char **names){ int r; size_t vsize; unsigned int channel; u_char *bufs[channels]; header(rtype, names[0]); set_params(); vsize = chunk_bytes / channels; // Not yet implemented assert(loaded == 0); for (channel = 0; channel < channels; ++channel) bufs[channel] = audiobuf + vsize * channel; while (count > 0) { size_t c = 0; size_t expected = count / channels; if (expected > vsize) expected = vsize; do { r = safe_read(fds[0], bufs[0], expected); if (r < 0) { perror(names[channel]); exit(EXIT_FAILURE); } for (channel = 1; channel < channels; ++channel) { if (safe_read(fds[channel], bufs[channel], r) != r) { perror(names[channel]); exit(EXIT_FAILURE); } } if (r == 0) break; c += r; } while (sleep_min == 0 && c < expected); c = c * 8 / bits_per_sample; r = pcm_writev(bufs, channels, c); if ((size_t)r != c) break; r = r * bits_per_frame / 8; count -= r; } snd_pcm_drain(handle);}void capturev_go(int* fds, unsigned int channels, off64_t count, int rtype, char **names){ size_t c; ssize_t r; unsigned int channel; size_t vsize; u_char *bufs[channels]; header(rtype, names[0]); set_params(); vsize = chunk_bytes / channels; for (channel = 0; channel < channels; ++channel) bufs[channel] = audiobuf + vsize * channel; while (count > 0) { size_t rv; c = count; if (c > chunk_bytes) c = chunk_bytes; c = c * 8 / bits_per_frame; if ((size_t)(r = pcm_readv(bufs, channels, c)) != c) break; rv = r * bits_per_sample / 8; for (channel = 0; channel < channels; ++channel) { if ((size_t)write(fds[channel], bufs[channel], rv) != rv) { perror(names[channel]); exit(EXIT_FAILURE); } } r = r * bits_per_frame / 8; count -= r; fdcount += r; }}static void playbackv(char **names, unsigned int count){ int ret = 0; unsigned int channel; unsigned int channels = rhwparams.channels; int alloced = 0; int fds[channels]; for (channel = 0; channel < channels; ++channel) fds[channel] = -1; if (count == 1 && channels > 1) { size_t len = strlen(names[0]); char format[1024]; memcpy(format, names[0], len); strcpy(format + len, ".%d"); len += 4; names = malloc(sizeof(*names) * channels); for (channel = 0; channel < channels; ++channel) { names[channel] = malloc(len); sprintf(names[channel], format, channel); } alloced = 1; } else if (count != channels) { error(_("You need to specify %d files"), channels); exit(EXIT_FAILURE); } for (channel = 0; channel < channels; ++channel) { fds[channel] = open(names[channel], O_RDONLY, 0); if (fds[channel] < 0) { perror(names[channel]); ret = EXIT_FAILURE; goto __end; } } /* should be raw data */ init_raw_data(); pbrec_count = calc_count(); playbackv_go(fds, channels, 0, pbrec_count, FORMAT_RAW, names); __end: for (channel = 0; channel < channels; ++channel) { if (fds[channel] >= 0) close(fds[channel]); if (alloced) free(names[channel]); } if (alloced) free(names); if (ret) exit(ret);}static void capturev(char **names, unsigned int count){ int ret = 0; unsigned int channel; unsigned int channels = rhwparams.channels; int alloced = 0; int fds[channels]; for (channel = 0; channel < channels; ++channel) fds[channel] = -1; if (count == 1) { size_t len = strlen(names[0]); char format[1024]; memcpy(format, names[0], len); strcpy(format + len, ".%d"); len += 4; names = malloc(sizeof(*names) * channels); for (channel = 0; channel < channels; ++channel) { names[channel] = malloc(len); sprintf(names[channel], format, channel); } alloced = 1; } else if (count != channels) { error(_("You need to specify %d files"), channels); exit(EXIT_FAILURE); } for (channel = 0; channel < channels; ++channel) { fds[channel] = open(names[channel], O_WRONLY + O_CREAT, 0644); if (fds[channel] < 0) { perror(names[channel]); ret = EXIT_FAILURE; goto __end; } } /* should be raw data */ init_raw_data(); pbrec_count = calc_count(); capturev_go(fds, channels, pbrec_count, FORMAT_RAW, names); __end: for (channel = 0; channel < channels; ++channel) { if (fds[channel] >= 0) close(fds[channel]); if (alloced) free(names[channel]); } if (alloced) free(names); if (ret) exit(ret);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?