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

📄 file.c

📁 使用在嵌入式linux平台或pc机上的wave文件录制和播放软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	 */	return wfile;}/* * Open /dev/dsp for reading or writing: */DSPFILE *OpenDSP(WAVFILE *wfile,int omode,ErrFunc erf) {	int e;					/* Saved errno value */	int t;					/* Work int */	unsigned long ul;			/* Work unsigned long */	DSPFILE *dfile = (DSPFILE *) malloc(sizeof (DSPFILE));	v_erf = erf;				/* Set error reporting function */	if ( dfile == NULL ) {		err("%s: Opening DSP device",sys_errlist[errno=ENOMEM]);		return NULL;	}	memset(dfile,0,sizeof *dfile);	dfile->dspbuf = NULL;	/*	 * Open the device driver:	 */	if ( (dfile->fd = open(env_AUDIODEV,omode,0)) < 0 ) {		err("%s:\nOpening audio device %s",			sys_errlist[errno],			env_AUDIODEV);		goto errxit;	}        /*         * Determine the audio device's block size.  Should be done after         * setting sampling rate etc.         */        if ( ioctl(dfile->fd,SNDCTL_DSP_GETBLKSIZE,&dfile->dspblksiz) < 0 ) {                err("%s: Optaining DSP's block size",sys_errlist[errno]);                goto errxit;        }         /*         * Check the range on the buffer sizes:         */        /* Minimum was 4096 but es1370 returns 1024 for 44.1kHz, 16 bit */        /* and 64 for 8130Hz, 8 bit */        if ( dfile->dspblksiz < 32 || dfile->dspblksiz > 65536 ) {                err("%s: Audio block size (%d bytes)",                        sys_errlist[errno=EINVAL],                        (int)dfile->dspblksiz);                goto errxit;        }         /*         * Allocate a buffer to do the I/O through:         */        if ( (dfile->dspbuf = (char *) malloc(dfile->dspblksiz)) == NULL ) {                err("%s: For DSP I/O buffer",sys_errlist[errno]);                goto errxit;        }	/*	 * Set the data bit size:	 */	t = wfile->wavinfo.DataBits;        if ( ioctl(dfile->fd,SNDCTL_DSP_SAMPLESIZE,&t) < 0 ) {		err("%s: Setting DSP to %u bits",sys_errlist[errno],(unsigned)t);		goto errxit;	}	/*	 * Set the mode to be Stereo or Mono:	 */	t = wfile->wavinfo.Channels == Stereo ? 1 : 0;	if ( ioctl(dfile->fd,SNDCTL_DSP_STEREO,&t) < 0 ) {		err("%s: Unable to set DSP to %s mode",			sys_errlist[errno],			t?"Stereo":"Mono");		goto errxit;	}		      	printf("Stereo Mode is %d!\n",t);	/*	 * Set the sampling rate:	 */	ul = wfile->wavinfo.SamplingRate;	if ( ioctl(dfile->fd,SNDCTL_DSP_SPEED,&ul) < 0 ) {		err("Unable to set audio sampling rate",sys_errlist[errno]);		goto errxit;	}	printf("Sampling rate is %ld!\n",ul);	/*	 * Return successfully opened device:	 */	return dfile;				/* Return file descriptor */	/*	 * Failed to open/initialize properly:	 */errxit:	e = errno;				/* Save the errno value */	if ( dfile->fd >= 0 )		close(dfile->fd);		/* Close device */	if ( dfile->dspbuf != NULL )		free(dfile->dspbuf);	free(dfile);	errno = e;				/* Restore error code */	return NULL;				/* Return error indication */}/* * Close the DSP device: */intCloseDSP(DSPFILE *dfile,ErrFunc erf) {	int fd;	v_erf = erf;				/* Set error reporting function */	if ( dfile == NULL ) {		err("%s: DSPFILE is not open",sys_errlist[errno=EINVAL]);		return -1;	}	fd = dfile->fd;	if ( dfile->dspbuf != NULL )		free(dfile->dspbuf);	free(dfile);		if ( close(fd) ) {		err("%s: Closing DSP fd %d",sys_errlist[errno],fd);		return -1;	}	return 0;}/* * Play DSP from WAV file: */intPlayDSP(DSPFILE *dfile,WAVFILE *wfile,DSPPROC work_proc,ErrFunc erf) {	UInt32 byte_count = (UInt32) wfile->wavinfo.Samples;	int bytes;	int n;	int byte_modulo;        int total_bytes, update_bytes;        SVRMSG msg;	v_erf = erf;				/* Set error reporting function */	/*	 * Check that the WAVFILE is open for reading:	 */	if ( wfile->rw != 'R' ) {		err("%s: WAVFILE must be open for reading",sys_errlist[errno=EINVAL]);		return -1;	}	/*	 * First determine how many bytes are required for each channel's sample:	 */	switch ( wfile->wavinfo.DataBits ) {	case 8 :		byte_count = 1;		break;	case 16 :		byte_count = 2;		break;	default :		err("%s: Cannot process %u bit samples",			sys_errlist[errno=EINVAL],			(unsigned)wfile->wavinfo.DataBits);		return -1;	}	/*	 * Allow for Mono/Stereo difference:	 */	if ( wfile->wavinfo.Channels == Stereo )		byte_count *= 2;		/* Twice as many bytes for stereo */	else if ( wfile->wavinfo.Channels != Mono ) {		err("%s: DSPFILE control block is corrupted (chan_mode)",			sys_errlist[errno=EINVAL]);		return -1;	}			byte_modulo = byte_count;				/* This many bytes per sample */	byte_count  = wfile->wavinfo.Samples * byte_modulo;	/* Total bytes to process */        total_bytes = byte_count;         /* Number of bytes to write between client updates.  Must be */        /* a multiple of dspblksiz.  */        update_bytes = ((wfile->wavinfo.SamplingRate*byte_modulo) / (RECPLAY_UPDATES_PER_SEC*dfile->dspblksiz)) * dfile->dspblksiz;	if ( ioctl(dfile->fd,SNDCTL_DSP_SYNC,0) != 0 )		err("%s: ioctl(%d,SNDCTL_DSP_SYNC,0)",sys_errlist[errno]);        /* Seek to requested start sample */        lseek(wfile->fd,wfile->StartSample*byte_modulo,SEEK_CUR); 	for ( ; byte_count > 0 && wfile->wavinfo.DataBytes > 0; byte_count -= (UInt32) n ) {		bytes = (int) ( byte_count > dfile->dspblksiz ? dfile->dspblksiz : byte_count );		if ( bytes > wfile->wavinfo.DataBytes )	/* Size bigger than data chunk? */			bytes = wfile->wavinfo.DataBytes;	/* Data chunk only has this much left */		if ( (n = read(wfile->fd,dfile->dspbuf,bytes)) != bytes ) {			if ( n >= 0 )				err("Unexpected EOF reading samples from WAV file",sys_errlist[errno=EIO]);			else	err("Reading samples from WAV file",sys_errlist[errno]);			goto errxit;		}                if ((clntIPC >= 0) && !((total_bytes-byte_count) % update_bytes)) {                        msg.msg_type = ToClnt_PlayState;                        msg.bytes = sizeof(msg.u.toclnt_playstate);                        msg.u.toclnt_playstate.SamplesLeft = byte_count / byte_modulo;                        msg.u.toclnt_playstate.CurrentSample =                          wfile->num_samples - msg.u.toclnt_playstate.SamplesLeft;                        MsgToClient(clntIPC,&msg,0);    /* Tell client playback status */                }		if ( write(dfile->fd,dfile->dspbuf,n) != n ) {			err("Writing samples to audio device",sys_errlist[errno]);			goto errxit;		}		wfile->wavinfo.DataBytes -= (UInt32) bytes;	/* We have fewer bytes left to read */		/*		 * The work procedure function is called when operating		 * in server mode to check for more server messages:		 */		if ( work_proc != NULL && work_proc(dfile) )	/* Did work_proc() return TRUE? */			break;					/* Yes, quit playing */	}			#if 0	/* I think this is doing a destructive flush: disabled */	if ( ioctl(dfile->fd,SNDCTL_DSP_SYNC,0) != 0 )		err("%s: ioctl(%d,SNDCTL_DSP_SYNC,0)",sys_errlist[errno]);#endif        /* Update client time display at end of sucessful play */        if (clntIPC >= 0) {                msg.msg_type = ToClnt_PlayState;                msg.bytes = sizeof(msg.u.toclnt_playstate);                msg.u.toclnt_playstate.SamplesLeft = byte_count / byte_modulo;                msg.u.toclnt_playstate.CurrentSample =                  wfile->num_samples - msg.u.toclnt_playstate.SamplesLeft;                MsgToClient(clntIPC,&msg,0);    /* Tell client playback status */        }	return 0;	/* All samples played successfully */errxit:	return -1;	/* Indicate error return */}/* * Record DSP to WAV file: If samples == 0UL, then record continues until * a bRecordStopPosted becomes true (via SIGINT). */intRecordDSP(DSPFILE *dfile,WAVFILE *wfile,UInt32 samples,DSPPROC work_proc,ErrFunc erf) {	UInt32 byte_count = (UInt32) wfile->wavinfo.Samples;	UInt32 chunk;	int bytes;	int n;	UInt32 bytes_per_sample = 0;	UInt32 bytes_written = 0;  	char *mybuf;	char *dspbuf_t;	char *dspbuf_p;	int i;	int update_bytes;        SVRMSG msg;	v_erf = erf;				/* Set error reporting function *///	char *mybuf;//	char *dspbuf_t;//	int i;	/*	 * Check that the WAVFILE is open for writing:	 */	if ( wfile->rw != 'W' ) {		err("WAVFILE must be open for writing",sys_errlist[errno=EINVAL]);		return -1;	}	/*	 * First determine how many bytes are required for each channel's sample:	 */	switch ( wfile->wavinfo.DataBits ) {	case 8 :		byte_count = 1;		break;	case 12 :	case 16 :		byte_count = 2;		break;	default :		err("Cannot process %u bit samples",			sys_errlist[errno=EINVAL],			(unsigned)wfile->wavinfo.DataBits);		return -1;	}	/*	 * Allow for Mono/Stereo difference:	 */	if ( wfile->wavinfo.Channels == Stereo )		byte_count *= 2;		/* Twice as many bytes for stereo */	else if ( wfile->wavinfo.Channels != Mono ) {		err("DSPFILE control block is corrupted (chan_mode)",sys_errlist[errno=EINVAL]);		return -1;	}			bytes_per_sample = byte_count;		/* Save for close later */	if ( samples > 0 )		byte_count *= wfile->wavinfo.Samples;	/* Total number of bytes to collect */	else	{		/* Compute a smallish sized chunk of the correct modulo bytes */		chunk = dfile->dspblksiz > 4096 ? 4096 : dfile->dspblksiz;		byte_count = (chunk + (byte_count-1)) & ~(byte_count-1);	}        /* Number of bytes to write between client updates.  Must be */        /* a multiple of dspblksiz. */        update_bytes = ((wfile->wavinfo.SamplingRate*bytes_per_sample)/            (RECPLAY_UPDATES_PER_SEC*dfile->dspblksiz))*dfile->dspblksiz;		mybuf=malloc(dfile->dspblksiz>>1);	memset(mybuf,0,(dfile->dspblksiz>>1)); 		while ( 1 ) {		/*		 * Determine how many samples to read:		 */		if ( samples > 0 )			bytes = byte_count > dfile->dspblksiz ? dfile->dspblksiz : byte_count;		else	bytes = byte_count;	/* Record until interrupted */		/*		 * Read a block of samples:		 */		if ( (n = read(dfile->fd,dfile->dspbuf,bytes)) < 0 ) {			err("Reading DSP device",sys_errlist[errno]);			goto errxit;		} else if ( n == 0 )			break;		dspbuf_t=mybuf;	 	dspbuf_p=dfile->dspbuf;		for(i=0;i<n/4;i++)		{			*mybuf++=*dfile->dspbuf++;			*mybuf++=*dfile->dspbuf++;			dfile->dspbuf+=2;		}		if(n%4!=0)		{			*mybuf++=*dfile->dspbuf++;			*mybuf++=*dfile->dspbuf++;			n=(n>>1)+1;		}		else			n=n>>1;		/*		 * Write a block of samples to the file:		 */		if ( (bytes = write(wfile->fd,dspbuf_t,n)) < 0 ) {			err("Writing WAV samples to %s",sys_errlist[errno],wfile->Pathname);			goto errxit;		} else if ( bytes != n ) {			if ( bytes > 0 )				bytes_written += bytes;			err("Did not write all WAV successfully",sys_errlist[errno=EIO]);			goto errxit;		}		mybuf=dspbuf_t;		dfile->dspbuf=dspbuf_p;		bytes_written += bytes;                if ((clntIPC >= 0) && !(bytes_written % update_bytes)) {                        msg.msg_type = ToClnt_RecState;                        msg.bytes = sizeof(msg.u.toclnt_recstate);                        msg.u.toclnt_recstate.bytes_written = bytes_written;                        msg.u.toclnt_recstate.num_samples = bytes_written / bytes_per_sample;                        MsgToClient(clntIPC,&msg,0);    /* Tell client playback status */                }		if ( samples > 0 )			if ( (byte_count -= (unsigned) n) < 1 )				break;		/*		 * The work procedure function is called when operating		 * in server mode to check for more server messages:		 */		if ( work_proc != NULL && work_proc(dfile) )	/* Did work_proc() return TRUE? */			break;					/* Yes, quit recording */	}	wfile->wavinfo.Samples = bytes_written & ~(bytes_per_sample-1);	return 0;	/* All samples played successfully */errxit:	wfile->wavinfo.Samples = bytes_written & ~(bytes_per_sample-1);	return -1;	/* Indicate error return */}/* $Source: /home/cvs/wavplay/file.c,v $ */

⌨️ 快捷键说明

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