⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aplay.c

📁 ALSA驱动的一些调试测试工具
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (hwparams.format == SND_PCM_FORMAT_FLOAT_LE)                f.format = LE_SHORT(WAV_FMT_IEEE_FLOAT);        else                f.format = LE_SHORT(WAV_FMT_PCM);	f.channels = LE_SHORT(hwparams.channels);	f.sample_fq = LE_INT(hwparams.rate);#if 0	tmp2 = (samplesize == 8) ? 1 : 2;	f.byte_p_spl = LE_SHORT(tmp2);	tmp = dsp_speed * hwparams.channels * (u_int) tmp2;#else	tmp2 = hwparams.channels * snd_pcm_format_physical_width(hwparams.format) / 8;	f.byte_p_spl = LE_SHORT(tmp2);	tmp = (u_int) tmp2 * hwparams.rate;#endif	f.byte_p_sec = LE_INT(tmp);	f.bit_p_spl = LE_SHORT(bits);	cd.type = WAV_DATA;	cd.length = LE_INT(cnt);	if (write(fd, &h, sizeof(WaveHeader)) != sizeof(WaveHeader) ||	    write(fd, &cf, sizeof(WaveChunkHeader)) != sizeof(WaveChunkHeader) ||	    write(fd, &f, sizeof(WaveFmtBody)) != sizeof(WaveFmtBody) ||	    write(fd, &cd, sizeof(WaveChunkHeader)) != sizeof(WaveChunkHeader)) {		error(_("write error"));		exit(EXIT_FAILURE);	}}/* write a Au-header */static void begin_au(int fd, size_t cnt){	AuHeader ah;	ah.magic = AU_MAGIC;	ah.hdr_size = BE_INT(24);	ah.data_size = BE_INT(cnt);	switch ((unsigned long) hwparams.format) {	case SND_PCM_FORMAT_MU_LAW:		ah.encoding = BE_INT(AU_FMT_ULAW);		break;	case SND_PCM_FORMAT_U8:		ah.encoding = BE_INT(AU_FMT_LIN8);		break;	case SND_PCM_FORMAT_S16_BE:		ah.encoding = BE_INT(AU_FMT_LIN16);		break;	default:		error(_("Sparc Audio doesn't support %s format..."), snd_pcm_format_name(hwparams.format));		exit(EXIT_FAILURE);	}	ah.sample_rate = BE_INT(hwparams.rate);	ah.channels = BE_INT(hwparams.channels);	if (write(fd, &ah, sizeof(AuHeader)) != sizeof(AuHeader)) {		error(_("write error"));		exit(EXIT_FAILURE);	}}/* closing .VOC */static void end_voc(int fd){	off64_t length_seek;	VocBlockType bt;	size_t cnt;	char dummy = 0;		/* Write a Terminator */	if (write(fd, &dummy, 1) != 1) {		error(_("write error"));		exit(EXIT_FAILURE);	}	length_seek = sizeof(VocHeader);	if (hwparams.channels > 1)		length_seek += sizeof(VocBlockType) + sizeof(VocExtBlock);	bt.type = 1;	cnt = fdcount;	cnt += sizeof(VocVoiceData);	/* Channel_data block follows */	if (cnt > 0x00ffffff)		cnt = 0x00ffffff;	bt.datalen = (u_char) (cnt & 0xFF);	bt.datalen_m = (u_char) ((cnt & 0xFF00) >> 8);	bt.datalen_h = (u_char) ((cnt & 0xFF0000) >> 16);	if (lseek64(fd, length_seek, SEEK_SET) == length_seek)		write(fd, &bt, sizeof(VocBlockType));	if (fd != 1)		close(fd);}static void end_wave(int fd){				/* only close output */	WaveChunkHeader cd;	off64_t length_seek;	off64_t filelen;	u_int rifflen;		length_seek = sizeof(WaveHeader) +		      sizeof(WaveChunkHeader) +		      sizeof(WaveFmtBody);	cd.type = WAV_DATA;	cd.length = fdcount > 0x7fffffff ? LE_INT(0x7fffffff) : LE_INT(fdcount);	filelen = fdcount + 2*sizeof(WaveChunkHeader) + sizeof(WaveFmtBody) + 4;	rifflen = filelen > 0x7fffffff ? LE_INT(0x7fffffff) : LE_INT(filelen);	if (lseek64(fd, 4, SEEK_SET) == 4)		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 */static 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 ((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_nonblock(handle, 0);	snd_pcm_drain(handle);	snd_pcm_nonblock(handle, nonblock);}/* *  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);}static 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 (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_nonblock(handle, 0);	snd_pcm_drain(handle);	snd_pcm_nonblock(handle, nonblock);}static 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(nam

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -