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

📄 wavfile.c

📁 qgo-1.5.4-r3.tar.gz linux下一个很好玩的游戏
💻 C
📖 第 1 页 / 共 2 页
字号:
	/*	 * Put little endian value into 32 bit value:	 */	dbytes = ubuf[3];	dbytes = (dbytes << 8) | ubuf[2];	dbytes = (dbytes << 8) | ubuf[1];	dbytes = (dbytes << 8) | ubuf[0];	wfile->wavinfo.DataBytes = dbytes;	/*	 * Open succeeded:	 */	return wfile;				/* Return open descriptor */	/*	 * Return error after failed open:	 */errxit:	e = errno;				/* Save errno */	free(wfile->Pathname);			/* Dispose of copied pathname */	free(wfile);				/* Dispose of WAVFILE struct */	errno = e;				/* Restore error number */	return NULL;				/* Return error indication */}/* * Apply command line option overrides to the interpretation of the input * wav file: * */voidWavReadOverrides(WAVFILE *wfile,WavPlayOpts *wavopts) {	UInt32 num_samples;	/*	 * Override sampling rate: -s sampling_rate	 */	if ( wavopts->SamplingRate.optChar != 0 ) {		wfile->wavinfo.SamplingRate = wavopts->SamplingRate.optValue;		wfile->wavinfo.bOvrSampling = 1;	}	/*	 * Override mono/stereo mode: -S / -M	 */	if ( wavopts->Channels.optChar != 0 ) {		wfile->wavinfo.Channels = wavopts->Channels.optValue;		wfile->wavinfo.bOvrMode = 1;	}	/*	 * Override the sample size in bits: -b bits	 */	if ( wavopts->DataBits.optChar != 0 ) {		wfile->wavinfo.DataBits = wavopts->DataBits.optValue;		wfile->wavinfo.bOvrBits = 1;	}        /*         * Set the first sample:         */        wfile->StartSample = 0;        num_samples = wfile->wavinfo.Samples = wfile->num_samples;        if ( wavopts->StartSample != 0 ) {                wfile->StartSample = wavopts->StartSample;                wfile->wavinfo.Samples -= wfile->StartSample;        }        /*         * Override # of samples if -t seconds option given:         */        if ( wavopts->Seconds != 0 ) {                wfile->wavinfo.Samples = wavopts->Seconds * wfile->wavinfo.SamplingRate;                if (wfile->StartSample+wfile->wavinfo.Samples > num_samples)                        wfile->wavinfo.Samples = num_samples-1;        }}/* * Close a WAVFILE */intWavClose(WAVFILE *wfile,ErrFunc erf) {	int e = 0;				/* Returned error code */	int channels;				/* Channels recorded in this wav file */	u_long samplerate;			/* Sampling rate */	int sample_bits;			/* data bit size (8/12/16) */	u_long samples;				/* The number of samples in this file */	u_long datastart;			/* The offset to the wav data */	long fpos;				/* File position in bytes */	v_erf = erf;				/* Set error reporting function */	if ( wfile == NULL ) {		err("%s: WAVFILE pointer is NULL!",sys_errlist[EINVAL]);		errno = EINVAL;		return -1;	}	/*	 * If the wav file was open for write, update the actual number	 * of samples written to the file:	 */	if ( wfile->rw == 'W' ) {		fpos = lseek(wfile->fd,0L,SEEK_CUR);	/* Get out file position */		if ( (e = WaveReadHeader(wfile->fd,&channels,&samplerate,&sample_bits,&samples,&datastart,_v_erf)) != 0 )			err("%s:\nReading WAV header from %s",emsg,wfile->Pathname);		else if ( lseek(wfile->fd,(long)(datastart-4),SEEK_SET) != (long)(datastart-4) )			err("%s:\nSeeking in WAV header file %s",sys_errlist[errno],wfile->Pathname);		else if ( write(wfile->fd,&wfile->wavinfo.Samples,sizeof wfile->wavinfo.Samples) != sizeof wfile->wavinfo.Samples )			err("%s:\nWriting in WAV header file %s",sys_errlist[errno],wfile->Pathname);		else	{			/*			 * 'data' chunk was updated OK: Now we have to update the RIFF block			 * count. Someday very soon, a real RIFF module is going to replace			 * this fudging.			 */			if ( ftruncate(wfile->fd,(size_t)fpos) )				err("%s:\nTruncating file %s to correct size",					sys_errlist[errno],					wfile->Pathname);			else if ( lseek(wfile->fd,4L,SEEK_SET) < 0L )				err("%s:\nSeek 4 for RIFF block update of %s",					sys_errlist[errno],					wfile->Pathname);			else	{				fpos -= 8;		/* Byte count for RIFF block */				if ( write(wfile->fd,&fpos,sizeof fpos) != sizeof fpos )					err("%s:\nUpdate of RIFF block count in %s failed",						sys_errlist[errno],						wfile->Pathname);			}		}	}	if ( close(wfile->fd) < 0 ) {		err("%s:\nClosing WAV file",sys_errlist[errno]);		e = errno;			/* Save errno value to return */	}	wavfile_free(wfile);			/* Release WAVFILE structure */	if ( (errno = e) != 0 )		return -1;			/* Failed exit */	return 0;				/* Successful exit */}/*/* * 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(AUDIODEV,omode,0)) < 0 ) {		err("%s:\nOpening audio device %s",			sys_errlist[errno],			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;	}	/*	 * 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;	}	/*	 * Return successfully opened device:	 */	return dfile;				/* Return file descriptor */	/*	 * Failed to open/initialize properly:	 */errxit:	e = errno;				/* Save the errno value */ fprintf(stdout, "error %s : \n",sys_errlist[errno]);	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 */}#endif

⌨️ 快捷键说明

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