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

📄 pc_wav.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
    {	error_msg("get_hd",		  "couldn't allocate storage for PC WAVE header.");	return NULL;    }    got_ck_hd = get_ck_hd(ckID, &ckSize, end_pref, &num_read, file);    while (got_ck_hd	   && strncmp(ckID, "fmt ", 4) != 0	   && strncmp(ckID, "data", 4) != 0)    {	got_ck_hd = (skip_ck(ckSize, end_pref, &num_read, file)		     && get_ck_hd(ckID, &ckSize, end_pref, &num_read, file));    }    if (!got_ck_hd)    {	error_msg("get_hd", "end of file within PC WAVE chunk.");	return NULL;    }    if (strncmp(ckID, "fmt ", 4) != 0)    {	error_msg("get_hd",		  "no \"fmt\" chunk before data in PC WAVE file.");	return NULL;    }    if (!(get_lsbf_ushort(&wav_hd->FormatTag, end_pref, &num_read, file)	  && get_lsbf_ushort(&wav_hd->Channels, end_pref, &num_read, file)	  && get_lsbf_ulong(&wav_hd->SamplesPerSec, end_pref, &num_read, file)	  && get_lsbf_ulong(&wav_hd->AvgBytesPerSec, end_pref, &num_read, file)	  && get_lsbf_ushort(&wav_hd->BlockAlign, end_pref, &num_read, file)))    {	error_msg("get_hd", "failed to read PC WAVE \"fmt\" chunk.");	return NULL;    }    ckSize -= 14;		/* 3 ushort & 2 ulong */    switch (wav_hd->FormatTag)    {    case WAVE_FORMAT_PCM:	if (!get_lsbf_ushort(&wav_hd->spec.pcm.BitsPerSample,			     end_pref, &num_read, file))	{	    error_msg("get_hd",		      "failed to read PC WAVE \"fmt\" chunk (PCM part).");	    return NULL;	}	ckSize -= 2;		/* 1 ushort */	break;    default:	error_msg("get_hd", "only WAVE_FORMAT_PCM supported.");	return NULL;    }    if (ckSize < 0)    {	error_msg("get_hd",		  "inconsistent chunk size for PC WAVE \"fmt\".");	return NULL;    }    do    {	got_ck_hd = (skip_ck(ckSize, end_pref, &num_read, file)		     && get_ck_hd(ckID, &ckSize, end_pref, &num_read, file));    } while(got_ck_hd	    && strncmp(ckID, "data", 4) != 0);    if (!got_ck_hd)    {	error_msg("get_hd", "failed to find PC WAVE \"data\" chunk.");	return NULL;    }    if (num_read > 0)    {	error_msg("get_hd", "read too far ahead.");	return NULL;    }    wav_hd->data_len = ckSize;    return wav_hd;}/* * Function used by "get_hd" to "read" a RIFF chunk header, consisting of * a four-character chunk ID and a four-byte unsigned integer chunk size * (in least-significant-first byte order).  These are returned via the * pointers "ckID" and "ckSize".  The eight bytes are obtained from the * sequence consisting of the catenation of (1) "num_read" bytes just * before the byte indicated by "end_pref" and (2) the unread bytes in * "file".  See "get_hd" for the usage of these last three arguments. The * return value is TRUE for success and FALSE for failure. */static intget_ck_hd(char		*ckID,	  unsigned long	*ckSize,	  char		*end_pref,	  int		*num_read,	  FILE		*file){    return (get_fourcc(ckID, end_pref, num_read, file)	    && get_lsbf_ulong(ckSize, end_pref, num_read, file));}/* * Function used by "get_hd" to skip over the body of a RIFF chunk after * its chunk ID and size have been obtained by "get_ck_hd".  The number * of bytes to skip is passed as "ckSize"; if this odd, an additional * byte of padding is skipped to make up an even number.  The bytes * skipped are in the sequence consisting of the catenation of * (1) "num_read" bytes just before the byte indicated by "end_pref" and * (2) the unread bytes in "file".  See "get_hd" for the usage of these * last three arguments.  Bytes are skipped by decrementing "num_read", * reading from "file", or both.  The return values is TRUE for success * and NO for failure. */static intskip_ck(unsigned long	ckSize,	char		*end_pref,	int		*num_read,	FILE		*file){    ckSize += (ckSize & 1);	/* round up to multiple of 2 bytes */    if (ckSize <= *num_read)    {	*num_read -= ckSize;    }    else    {	ckSize -= *num_read;	*num_read = 0;	while (ckSize > 0 && getc(file) != EOF)	    ckSize--;	if (ckSize != 0)	{	    error_msg("skip_ck", "end of file within chunk.");	    return NO;	}    }    return YES;}/* * Function used by "get_hd" to "read" a two-byte unsigned short integer * in least-significant-first byte order from the sequence consisting of * the catenation of (1) "num_read" bytes just before the byte indicated * by "end_pref" and (2) the unread bytes in "file".  See "get_hd" for * the usage of these last three arguments.  The value obtained is * returned via the pointer "ptr".  The function return value is TRUE * for success and FALSE for failure. */static intget_lsbf_ushort(unsigned short	*ptr,		char		*end_pref,		int		*num_read,		FILE		*file){    int		    ch;    unsigned short  val;    ch = next_char(end_pref, num_read, file);    if (ch == EOF)	return NO;    val = (ch & 0xff);    ch = next_char(end_pref, num_read, file);    if (ch == EOF)	return NO;    *ptr = val | (ch & 0xff);    return YES;}/* * Function used by "get_hd" and "get_ck_hd" to "read" a two-byte * unsigned short integer in least-significant-first byte order from the * sequence consisting of the catenation of (1) "num_read" bytes just * before the byte indicated by "end_pref" and (2) the unread bytes in * "file".  See "get_hd" for the usage of these last three arguments. * The value obtained is returned via the pointer "ptr".  The function * return value is TRUE for success and FALSE for failure. */static intget_lsbf_ulong(unsigned long	*ptr,	       char		*end_pref,	       int		*num_read,	       FILE		*file){    int		    i;    int		    ch;    unsigned long   val;    val = 0;    for (i = 0; i < 4; i++)    {	ch = next_char(end_pref, num_read, file);	if (ch != EOF)	    val |= (ch & 0xff) << (8*i);	else	    return NO;    }    *ptr = val;    return YES;}/* * Function used by "get_ck_hd" to "read" a four-character chunk ID from * the sequence consisting of the catenation of (1) "num_read" bytes just * before the byte indicated by "end_pref" and (2) the unread bytes in * "file".  See "get_hd" for the usage of these last three arguments. * The value obtained is returned via the pointer "ptr".  The function * return value is TRUE for success and FALSE for failure. */static intget_fourcc(char     *ptr,	   char     *end_pref,	   int	    *num_read,	   FILE     *file){    int	    i;    int	    ch;    for (i= 0; i < 4; i++)    {	ch = next_char(end_pref, num_read, file);	if (ch != EOF)	    ptr[i] = ch;	else	    return NO;    }    return YES;}/* * Function used by "get_lsbf_ushort", "get_lsbf_ulong", "get_fourcc", to * "read" the next byte (unsigned char) from the sequence consisting of * the catenation of (1) "num_read" bytes just before the byte indicated * by "end_pref" and (2) the unread bytes in "file".  See "get_hd" for * the usage of these last three arguments.  The return value is the * value obtained in case of success and EOF in case of failure. */static intnext_char(char	*end_pref,	  int	*num_read,	  FILE	*file){    return ((*num_read > 0)	    ? (unsigned char) *(end_pref - (*num_read)--)	    : getc(file));}/* * Function used by "pc_wav_get_rec" and "pc_wav_getsd_recs" to read a * given number "len" of two-byte signed short integers in * least-significant-first byte order from a file.  The values obtained * are returned via the pointer "ptr".  The function return value is the * actual number of values read and is less than "len" in case of * failure. */static longread_lsbf_short(short	*ptr,		long	len,		FILE	*file){#if defined(DEC_ALPHA) || defined(LINUX)    /* Code for Vax-like architectures (including Intel) that     * match the least-significant-first byte ordering of the     * RIFF standard.     */    return fread(ptr, 2, len, file);#elif defined(SUN4) || defined(HP700) || defined(SG)    /* Code for Sun-like architectures with most-significant-first     * byte ordering, requiring byte-swapping to read RIFF files.     */    unsigned char   *p = (unsigned char *) ptr;    int		    ch;    long	    n, i;    if (len == 1)    {	if ((ch = getc(file)) == EOF)	    return 0;	p[1] = (unsigned char) ch;	if ((ch = getc(file)) == EOF)	    return 0;		p[0] = (unsigned char) ch;	return 1;    }    if (len <= 0)	return 0;    /* Read the data offset by 1 so that the low-order bytes end up in the     * right places and don't have to be moved when we "swap".     */    n = fread(p + 1, 1, 2*len - 1, file);    /* Now move the high-order bytes into place.     */    for (i = 0; i < n - 1; i += 2)	p[i] = p[i+2];    if (n != 2*len - 1)	return n/2;    if ((ch = getc(file)) == EOF)	return n/2;    p[n - 1] = (unsigned char) ch;    return len;#else    /* Code for unknown architecture.     * This should work regardless of the native byte order of the     * maching on which it runs.  However, when porting to another     * machine, try adding it to one of the #ifdef's above, as it     * is likely to be faster.     */    long            n;    unsigned int    item;    int             ch;    for (n = 0; n < len; n++)    {	if ((ch = getc(file)) == EOF)	    break;	item = ch & 0xff;	if ((ch = getc(file)) == EOF)	    break;	item |= (ch & 0xff) << 8;	ptr[n] =	    (item & 0x8000)		? (-1 - (int) (item ^ 0xffff))		    : item;    }    return n;#endif}/* * Function used by various functions in this module to output error * messages. */static voiderror_msg(char *func_name, char *msg){    (void) fprintf(stderr, "%s: %s\n", func_name, msg);}

⌨️ 快捷键说明

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