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

📄 wav.c

📁 linux下录音程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	break;	    case WAVE_FORMAT_ADPCM:    case WAVE_FORMAT_IMA_ADPCM:	if (ft->info.style == -1 || ft->info.style == ADPCM)	    ft->info.style = ADPCM;	else	    warn("User options overriding style read in .wav header");	break;	    case WAVE_FORMAT_ALAW:	/* Think I can handle this */	if (ft->info.style == -1 || ft->info.style == ALAW)	    ft->info.style = ALAW;	else	    warn("User options overriding style read in .wav header");	break;	    case WAVE_FORMAT_MULAW:	/* Think I can handle this */	if (ft->info.style == -1 || ft->info.style == ULAW)	    ft->info.style = ULAW;	else	    warn("User options overriding style read in .wav header");	break;	    case WAVE_FORMAT_OKI_ADPCM:	fail("Sorry, this WAV file is in OKI ADPCM format.");    case WAVE_FORMAT_DIGISTD:	fail("Sorry, this WAV file is in Digistd format.");    case WAVE_FORMAT_DIGIFIX:	fail("Sorry, this WAV file is in Digifix format.");    case IBM_FORMAT_MULAW:	fail("Sorry, this WAV file is in IBM U-law format.");    case IBM_FORMAT_ALAW:	fail("Sorry, this WAV file is in IBM A-law format.");    case IBM_FORMAT_ADPCM:	fail("Sorry, this WAV file is in IBM ADPCM format.");    default:	fail("WAV file has unknown format type");    }    wChannels = rlshort(ft);    len -= 2;    /* User options take precedence */    if (ft->info.channels == -1 || ft->info.channels == wChannels)	ft->info.channels = wChannels;    else	warn("User options overriding channels read in .wav header");	    wSamplesPerSecond = rllong(ft);    len -= 4;    if (ft->info.rate == 0 || ft->info.rate == wSamplesPerSecond)	ft->info.rate = wSamplesPerSecond;    else	warn("User options overriding rate read in .wav header");        wAvgBytesPerSec = rllong(ft);	/* Average bytes/second */    wav->blockAlign = rlshort(ft);	/* Block align */    len -= 6;    /* bits per sample per channel */	    wBitsPerSample =  rlshort(ft);    len -= 2;    /* ADPCM formats have extended fmt chunk.  Check for those cases. */    if (wav->formatTag == WAVE_FORMAT_ADPCM)    {	if (wBitsPerSample != 4)	    fail("Can only handle 4-bit MS ADPCM in wav files");	wExtSize = rlshort(ft);	wav->samplesPerBlock = rlshort(ft);	wav->bytesPerBlock = (wav->samplesPerBlock + 7)/2 * ft->info.channels;	wNumCoefs = rlshort(ft);	wav->packet = (unsigned char *)malloc(wav->blockAlign);	len -= 6;	    	wav->samples[1] = wav->samples[0] = 0;	/* Use ft->info.channels after this becuase wChannels is now bad */	while (wChannels-- > 0)	    wav->samples[wChannels] = (short *)malloc(wav->samplesPerBlock*sizeof(short));    }    else if (wav->formatTag == WAVE_FORMAT_IMA_ADPCM)    {	if (wBitsPerSample != 4)	    fail("Can only handle 4-bit IMA ADPCM in wav files");	wExtSize = rlshort(ft);	wav->samplesPerBlock = rlshort(ft);	wav->bytesPerBlock = (wav->samplesPerBlock + 7)/2 * ft->info.channels;	wav->packet = (unsigned char *)malloc(wav->blockAlign);	len -= 4;	    	wav->samples[1] = wav->samples[0] = 0;	/* Use ft->info.channels after this becuase wChannels is now bad */	while (wChannels-- > 0)	    wav->samples[wChannels] = (short *)malloc(wav->samplesPerBlock*sizeof(short));    }    bytespersample = (wBitsPerSample + 7)/8;    switch (bytespersample)    {	    case BYTE:	/* User options take precedence */	if (ft->info.size == -1 || ft->info.size == BYTE)	    ft->info.size = BYTE;	else	    warn("User options overriding size read in .wav header");	if (ft->info.style == -1 || ft->info.style == UNSIGNED)	    ft->info.style = UNSIGNED;	else if (ft->info.style != ALAW && ft->info.style != ULAW &&		 ft->info.style != ADPCM) 	    warn("User options overriding style read in .wav header");	break;	    case WORD:	if (ft->info.size == -1 || ft->info.size == WORD)	    ft->info.size = WORD;	else	    warn("User options overriding size read in .wav header");	if (ft->info.style == -1 || ft->info.style == SIGN2)	    ft->info.style = SIGN2;	else	    warn("User options overriding style read in .wav header");	break;	    case DWORD:	if (ft->info.size == -1 || ft->info.size == DWORD)	    ft->info.size = DWORD;	else	    warn("User options overriding size read in .wav header");	if (ft->info.style == -1 || ft->info.style == SIGN2)	    ft->info.style = SIGN2;	else	    warn("User options overriding style read in .wav header");	break;	    default:	fail("Sorry, don't understand .wav size");    }    /* Skip past the rest of any left over fmt chunk */    while (len > 0 && !feof(ft->fp))    {	getc(ft->fp);	len--;    }    /* Now look for the wave data chunk */    for (;;)    {	if ( fread(magic, 1, 4, ft->fp) != 4 )	    fail("WAVE file has missing data chunk");	len = rllong(ft);	if (strncmp("data", magic, 4) == 0)	    break;				/* Found the data chunk */		while (len > 0 && !feof(ft->fp)) 	/* skip to next chunk */	{	    getc(ft->fp);	    len--;	}    }        data_length = len;    if (wav->formatTag == WAVE_FORMAT_ADPCM)    {	/* Compute easiest part of number of samples.  For every block, there	   are samplesPerBlock samples to read. */	wav->numSamples = (((data_length / wav->blockAlign) * wav->samplesPerBlock) * ft->info.channels);	/* Next, for any partial blocks, substract overhead from it and it	   will leave # of samples to read. */	wav->numSamples += ((data_length - ((data_length/wav->blockAlign)					    *wav->blockAlign))			    - (6 * ft->info.channels)) * ft->info.channels;	wav->blockSamplesRemaining = 0;	       /* Samples left in buffer */    }    else if (wav->formatTag == WAVE_FORMAT_IMA_ADPCM)    {	/* Compute easiest part of number of samples.  For every block, there	   are samplesPerBlock samples to read. */	wav->numSamples = (((data_length / wav->blockAlign) * wav->samplesPerBlock) * ft->info.channels);	/* Next, for any partial blocks, substract overhead from it and it	   will leave # of samples to read. */	wav->numSamples += ((data_length - ((data_length/wav->blockAlign)					    *wav->blockAlign))			    - (3 * ft->info.channels)) * ft->info.channels;	wav->blockSamplesRemaining = 0;	       /* Samples left in buffer */    }    else	wav->numSamples = data_length/ft->info.size;	/* total samples */    report("Reading Wave file: %s format, %d channel%s, %d samp/sec",	   wav_format_str(wav->formatTag), ft->info.channels,	   wChannels == 1 ? "" : "s", wSamplesPerSecond);    report("        %d byte/sec, %d block align, %d bits/samp, %u data bytes",	   wAvgBytesPerSec, wav->blockAlign, wBitsPerSample, data_length);    /* Can also report exteded fmt information */    if (wav->formatTag == WAVE_FORMAT_ADPCM)	report("        %d Extsize, %d Samps/block, %d bytes/block %d Num Coefs\n",wExtSize,wav->samplesPerBlock,wav->bytesPerBlock,wNumCoefs);    else if (wav->formatTag == WAVE_FORMAT_IMA_ADPCM)	report("        %d Extsize, %d Samps/block, %d bytes/block\n",wExtSize,wav->samplesPerBlock,wav->bytesPerBlock);}/* * Read up to len samples from file. * Convert to signed longs. * Place in buf[]. * Return number of samples read. */LONG wavread(ft, buf, len) ft_t ft;LONG *buf, len;{	wav_t	wav = (wav_t) ft->priv;	LONG	done;		if (len > wav->numSamples) len = wav->numSamples;	/* If file is in ADPCM style then read in multiple blocks else */	/* read as much as possible and return quickly. */	if (ft->info.style == ADPCM)	{	    done = 0;	    while (done < len) { /* Still want data? */		/* See if need to read more from disk */		if (wav->blockSamplesRemaining == 0) { 		    if (wav->formatTag == WAVE_FORMAT_IMA_ADPCM)			wav->blockSamplesRemaining = ImaAdpcmNextBlock(ft);		    else			wav->blockSamplesRemaining = MsAdpcmNextBlock(ft);		    if (wav->blockSamplesRemaining == 0)		    {			/* Don't try to read any more samples */			wav->numSamples = 0;			return done;		    }		    wav->samplePtr[0] = wav->samples[0];		    wav->samplePtr[1] = wav->samples[1];		}		switch(ft->info.channels) { /* Copy data into buf */		case 1: /* Mono: Just copy left channel data */		    while ((wav->blockSamplesRemaining > 0) && (done < len))		    {			/* Output is already signed */			*buf++ = LEFT(*(wav->samplePtr[0]++), 16);			done++;			wav->blockSamplesRemaining--;		    }		    break;		case 2: /* Stereo: Interleave samples */		    while ((wav->blockSamplesRemaining > 0) && (done < len))		    {			/* Output is already signed */			*buf++ = LEFT(*(wav->samplePtr[0]++),16); /* Left */			*buf++ = LEFT(*(wav->samplePtr[1]++),16); /* Right */			done += 2;			wav->blockSamplesRemaining--;		    }		    break;		default:		    fail ("Can only handle stereo or mono files");		}	    }	}	else /* else not ADPCM style */	{	    done = rawread(ft, buf, len);	    /* If software thinks there are more samples but I/O */	    /* says otherwise, let the user no about this.       */	    if (done == 0 && wav->numSamples != 0)		warn("Premature EOF on .wav input file");	}	wav->numSamples -= done;	return done;}/* * Do anything required when you stop reading samples.   * Don't close input file!  */void wavstopread(ft) ft_t ft;{    wav_t	wav = (wav_t) ft->priv;    if (wav->packet) free(wav->packet);    if (wav->samples[0]) free(wav->samples[0]);    if (wav->samples[1]) free(wav->samples[1]);}void wavstartwrite(ft) ft_t ft;{	wav_t	wav = (wav_t) ft->priv;	int	littlendian = 1;	char	*endptr;	endptr = (char *) &littlendian;	if (!*endptr) ft->swap = 1;	wav->numSamples = 0;	wav->second_header = 0;	if (! ft->seekable)		warn("Length in output .wav header will wrong since can't seek to fix it");	wavwritehdr(ft);}void wavwritehdr(ft) ft_t ft;{	wav_t	wav = (wav_t) ft->priv;        /* wave file characteristics */        unsigned short wFormatTag = 0;          /* data format */        unsigned short wChannels;               /* number of channels */        ULONG  wSamplesPerSecond;       	/* samples per second per channel */        ULONG  wAvgBytesPerSec;        		 /* estimate of bytes per second needed */        unsigned short wBlockAlign;             /* byte alignment of a basic sample block */        unsigned short wBitsPerSample;          /* bits per sample */        ULONG  data_length;             	/* length of sound data in bytes */	ULONG  bytespersample; 			/* bytes per sample (per channel) */	switch (ft->info.size)	{		case BYTE:			if (ft->info.style == -1 || ft->info.style == UNSIGNED)				ft->info.style = UNSIGNED;			else if (!wav->second_header && ft->info.style != ALAW && ft->info.style != ULAW && ft->info.style != ADPCM) 				warn("User options overriding style written to .wav header");			if (ft->info.style == ADPCM)			{			    warn("Can not support writing ADPCM style. Overriding to UNSIGNED\n");			    ft->info.style = UNSIGNED;			    wBitsPerSample = 8;			    /* wBitsPerSample = 4; */			}			else				wBitsPerSample = 8;			break;		case WORD:			wBitsPerSample = 16;			if (ft->info.style == -1 || ft->info.style == SIGN2)				ft->info.style = SIGN2;			else if (!wav->second_header)				warn("User options overriding style written to .wav header");			break;		case DWORD:			wBitsPerSample = 32;			if (ft->info.style == -1 || ft->info.style == SIGN2)				ft->info.style = SIGN2; 			else if (!wav->second_header)				warn("User options overriding style written to .wav header");			break;		default:			wBitsPerSample = 32;			if (ft->info.style == -1)				ft->info.style = SIGN2; 			if (!wav->second_header)				warn("Warning - writing bad .wav file using %s",sizes[ft->info.size]);			break;	}	switch (ft->info.style)	{		case UNSIGNED:			wFormatTag = WAVE_FORMAT_PCM;			if (wBitsPerSample != 8 && !wav->second_header)				warn("Warning - writing bad .wav file using unsigned data and %d bits/sample",wBitsPerSample);			break;		case SIGN2:			wFormatTag = WAVE_FORMAT_PCM;			if (wBitsPerSample == 8 && !wav->second_header)				warn("Warning - writing bad .wav file using signed data and %d bits/sample",wBitsPerSample);			break;		case ALAW:			wFormatTag = WAVE_FORMAT_ALAW;			if (wBitsPerSample != 8 && !wav->second_header)				warn("Warning - writing bad .wav file using A-law data and %d bits/sample",wBitsPerSample);			break;		case ULAW:			wFormatTag = WAVE_FORMAT_MULAW;			if (wBitsPerSample != 8 && !wav->second_header)				warn("Warning - writing bad .wav file using U-law data and %d bits/sample",wBitsPerSample);			break;		case ADPCM:			wFormatTag = WAVE_FORMAT_IMA_ADPCM;			if (wBitsPerSample != 4 && !wav->second_header)			warn("Warning - writing bad .wav file using IMA ADPCM and %d bits/sample",wBitsPerSample);			break;	}			wSamplesPerSecond = ft->info.rate;	bytespersample = (wBitsPerSample + 7)/8;	wAvgBytesPerSec = ft->info.rate * ft->info.channels * bytespersample;	wChannels = ft->info.channels;	wBlockAlign = ft->info.channels * bytespersample;	if (!wav->second_header)	/* use max length value first time */		data_length = 0x7fffffffL - (8+16+12);	else	/* fixup with real length */	{	    if (ft->info.style == ADPCM)		data_length = wav->numSamples / 2;	    else		data_length = bytespersample * wav->numSamples;	}	/* figured out header info, so write it */	fputs("RIFF", ft->fp);	wllong(ft, data_length + 8+16+12);	/* Waveform chunk size: FIXUP(4) */	fputs("WAVE", ft->fp);	fputs("fmt ", ft->fp);	wllong(ft, (LONG)16);		/* fmt chunk size */	wlshort(ft, wFormatTag);	wlshort(ft, wChannels);	wllong(ft, wSamplesPerSecond);	wllong(ft, wAvgBytesPerSec);	wlshort(ft, wBlockAlign);	wlshort(ft, wBitsPerSample);		fputs("data", ft->fp);	wllong(ft, data_length);		/* data chunk size: FIXUP(40) */	if (!wav->second_header) {		report("Writing Wave file: %s format, %d channel%s, %d samp/sec",	        	wav_format_str(wFormatTag), wChannels,	        	wChannels == 1 ? "" : "s", wSamplesPerSecond);		report("        %d byte/sec, %d block align, %d bits/samp",	                wAvgBytesPerSec, wBlockAlign, wBitsPerSample);	} else		report("Finished writing Wave file, %u data bytes\n",data_length);}void wavwrite(ft, buf, len) ft_t ft;LONG *buf, len;{	wav_t	wav = (wav_t) ft->priv;	wav->numSamples += len;	rawwrite(ft, buf, len);}voidwavstopwrite(ft) ft_t ft;{	/* All samples are already written out. */	/* If file header needs fixing up, for example it needs the */ 	/* the number of samples in a field, seek back and write them here. */	if (!ft->seekable)		return;	if (fseek(ft->fp, 0L, 0) != 0)		fail("Sorry, can't rewind output file to rewrite .wav header.");	((wav_t) ft->priv)->second_header = 1;	wavwritehdr(ft);}/* * Return a string corresponding to the wave format type. */static char *wav_format_str(wFormatTag) unsigned wFormatTag;{	switch (wFormatTag)	{		case WAVE_FORMAT_UNKNOWN:			return "Microsoft Official Unknown";		case WAVE_FORMAT_PCM:			return "Microsoft PCM";		case WAVE_FORMAT_ADPCM:			return "Microsoft ADPCM";		case WAVE_FORMAT_ALAW:			return "Microsoft A-law";		case WAVE_FORMAT_MULAW:			return "Microsoft U-law";		case WAVE_FORMAT_OKI_ADPCM:			return "OKI ADPCM format.";		case WAVE_FORMAT_IMA_ADPCM:			return "IMA ADPCM";		case WAVE_FORMAT_DIGISTD:			return "Digistd format.";		case WAVE_FORMAT_DIGIFIX:			return "Digifix format.";		case IBM_FORMAT_MULAW:			return "IBM U-law format.";		case IBM_FORMAT_ALAW:			return "IBM A-law";                case IBM_FORMAT_ADPCM:                	return "IBM ADPCM";		default:			return "Unknown";	}}

⌨️ 快捷键说明

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