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

📄 headers.c

📁 音频信号的重采样程序,如44.1K的WAV转换成采样频率为48K的WAV.
💻 C
📖 第 1 页 / 共 5 页
字号:
#define DPOW2TO31	((double)2147483648.0)	/* 2^31 */static double myUlongToDouble(unsigned int ul){  double val;  if(ul & ULPOW2TO31) val = DPOW2TO31 + (ul & (~ULPOW2TO31));  else val = ul;  return val;}static unsigned int myDoubleToUlong(double val){  unsigned int ul;  if(val < DPOW2TO31) ul = (unsigned int)val;  else ul = ULPOW2TO31 | (unsigned int)(val-DPOW2TO31);  return ul;}static double ieee_80_to_double(unsigned char *p){  unsigned char sign;  short lexp = 0;  unsigned int mant1 = 0;  unsigned int mant0 = 0;  lexp = *p++;  lexp <<= 8;  lexp |= *p++;  sign = (lexp & 0x8000) ? 1 : 0;  lexp &= 0x7FFF;  mant1 = *p++;  mant1 <<= 8;  mant1 |= *p++;  mant1 <<= 8;  mant1 |= *p++;  mant1 <<= 8;  mant1 |= *p++;  mant0 = *p++;  mant0 <<= 8;  mant0 |= *p++;  mant0 <<= 8;  mant0 |= *p++;  mant0 <<= 8;  mant0 |= *p++;  if(mant1 == 0 && mant0 == 0 && lexp == 0 && sign == 0)    return 0.0;  else    {      double val;      val = myUlongToDouble(mant0) * pow(2.0, -63.0);      val += myUlongToDouble(mant1) * pow(2.0, -31.0);      val *= pow(2.0, ((double) lexp) - 16383.0);      return sign ? -val : val;    }}static void double_to_ieee_80(double val, unsigned char *p){  short lexp = 0;  unsigned char sign = 0;  unsigned int mant1 = 0;  unsigned int mant0 = 0;  if(val < 0.0)	{  sign = 1;  val = -val; }  if(val != 0.0)	/* val identically zero -> all elements zero */    {      lexp = (short)(log(val) / log(2.0) + 16383.0);      val *= pow(2.0, 31.0 + 16383.0 - (double)lexp);      mant1 = myDoubleToUlong(val);      val -= myUlongToDouble(mant1);      val *= pow(2.0, 32.0);      mant0 = myDoubleToUlong(val);    }  *p++ = ((sign << 7) | (lexp >> 8));  *p++ = 0xFF & lexp;    *p++ = 0xFF & (mant1 >> 24);  *p++ = 0xFF & (mant1 >> 16);  *p++ = 0xFF & (mant1 >> 8);  *p++ = 0xFF & (mant1);  *p++ = 0xFF & (mant0 >> 24);  *p++ = 0xFF & (mant0 >> 16);  *p++ = 0xFF & (mant0 >> 8);  *p++ = 0xFF & (mant0);}static off_t update_form_size, update_frames_location, update_ssnd_location;static int seek_and_read(int chan, unsigned char *buf, off_t offset, int nbytes){  if (offset < 0) return(-1);  lseek(chan, offset, SEEK_SET);  return(read(chan, buf, nbytes));}static int read_aiff_marker(int m, unsigned char *buf){  int psize;  marker_ids[m] = mus_char_to_bshort((unsigned char *)buf);  marker_positions[m] = mus_char_to_bint((unsigned char *)(buf + 2));  psize = (int)buf[6] + 1;   if (psize & 1) psize++;   return(psize+6);}static int read_aiff_header(const char *filename, int chan, int overall_offset){  /* we know we have checked for FORM xxxx AIFF|AIFC when we arrive here */  /* as far as I can tell, the COMM block has the header data we seek, and the SSND block has the sound data */  int chunksize, chunkloc, i, j, ssnd_bytes = 0;  bool happy, got_comm = false;  off_t offset;  type_specifier = mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 8 + overall_offset));  update_ssnd_location = 0;  chunkloc = 12 + overall_offset;  offset = 0;  for (i = 0; i < AUX_COMMENTS; i++) aux_comment_start[i] = 0;  data_format = MUS_BSHORT;  srate = 0;  chans = 0;  happy = true;  true_file_length = SEEK_FILE_LENGTH(chan);  update_form_size = mus_char_to_bint((unsigned char *)(hdrbuf + 4 + overall_offset)); /* should be file-size-8 unless there are multiple forms */  while (happy)    {      offset += chunkloc;      if (seek_and_read(chan, (unsigned char *)hdrbuf, offset, 32) <= 0)	{	  if ((got_comm) && (data_location > 0))	    {	      mus_print("%s, aiff header: chunks confused at " OFF_TD "; will try to continue", filename, offset);	      break;	    }	  return(mus_error(MUS_HEADER_READ_FAILED, "%s, aiff header: chunks confused at " OFF_TD , filename, offset));	}      chunksize = mus_char_to_bint((unsigned char *)(hdrbuf + 4));      if ((chunksize == 0) && /* can be empty data chunk */	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))	break;      /* fprintf(stderr,"chunk: %c%c%c%c for %d\n", hdrbuf[0], hdrbuf[1], hdrbuf[2], hdrbuf[3], chunksize); */      if (match_four_chars((unsigned char *)hdrbuf, I_COMM))	{	  int frames;	  got_comm = true;	  chans = mus_char_to_bshort((unsigned char *)(hdrbuf + 8));	  frames = mus_char_to_ubint((unsigned char *)(hdrbuf + 10)); /* was bint 27-Jul-01 */	  update_frames_location = 10 + offset;	  original_data_format = mus_char_to_bshort((unsigned char *)(hdrbuf + 14));	  if ((original_data_format % 8) != 0) 	    {	      /* weird sizes are legal --	       * these samples are left-justified (and zero padded on the right), so	       * we can handle any bit size by rounding up to the nearest byte.	       */	      original_data_format = 8 * (1 + (original_data_format >> 3));	    }	  if (original_data_format == 8) data_format = MUS_BYTE;	  else if (original_data_format == 16) data_format = MUS_BSHORT;	  else if (original_data_format == 24) data_format = MUS_B24INT;	  else if (original_data_format == 32) data_format = MUS_BINT;	  else if (original_data_format == 64) data_format = MUS_BDOUBLE;	  else return(mus_error(MUS_HEADER_READ_FAILED, "%s: bits per sample: %d?", filename, mus_char_to_bshort((unsigned char *)(hdrbuf + 14))));	  srate = (int)ieee_80_to_double((unsigned char *)(hdrbuf + 16));	  /* if AIFC, compression type over-rides (possibly bogus) original_data_format */	  if (type_specifier == mus_char_to_uninterpreted_int((unsigned const char *)I_AIFC))	    {	      /* some aifc files assume the compression field is a new and very weird chunk!! -- surely a bug? */	      /* AIFF spec says COMM size is always 18, but this is amended in the newer AIFC spec */	      if (chunksize == 18) chunksize += (5 + ((int)hdrbuf[30]));             /* 5 = chunk header length in this case */	      if ((!(match_four_chars((unsigned char *)(hdrbuf + 26), I_NONE))) &&		  (!(match_four_chars((unsigned char *)(hdrbuf + 26), I_twos))))		{		  original_data_format = mus_char_to_uninterpreted_int((unsigned char *)(hdrbuf + 26));		  if ((match_four_chars((unsigned char *)(hdrbuf + 26), I_ALAW)) || 		      (match_four_chars((unsigned char *)(hdrbuf + 26), I_alaw)))		    data_format = MUS_ALAW;		  else 		    {		      if ((match_four_chars((unsigned char *)(hdrbuf + 26), I_ULAW)) ||			  (match_four_chars((unsigned char *)(hdrbuf + 26), I_ulaw)))			data_format = MUS_MULAW;		      else 			{			  if ((match_four_chars((unsigned char *)(hdrbuf + 26), I_sowt)) ||			      (match_four_chars((unsigned char *)(hdrbuf + 26), I_ni23)))			    {			      /* Sound.h sez sowt is just 16-bit format */			      if (data_format == MUS_BSHORT) data_format = MUS_LSHORT;			      else if (data_format == MUS_B24INT) data_format = MUS_L24INT;			      else if (data_format == MUS_BINT) data_format = MUS_LINT;			    }			  else			    {			      if (match_four_chars((unsigned char *)(hdrbuf + 26), I_raw_))				{				  if (data_format == MUS_BYTE) data_format = MUS_UBYTE;				  else if (data_format == MUS_BSHORT) data_format = MUS_UBSHORT;				}			      else				{				  if ((match_four_chars((unsigned char *)(hdrbuf + 26), I_fl32)) ||				      (match_four_chars((unsigned char *)(hdrbuf + 26), I_FL32)))				    data_format = MUS_BFLOAT;				  else				    {				      if (match_four_chars((unsigned char *)(hdrbuf + 26), I_fl64))					data_format = MUS_BDOUBLE;				      else					{					  if (match_four_chars((unsigned char *)(hdrbuf + 26), I_ima4))					    {					      block_align = 34;					      original_data_format = MUS_AIFF_IMA_ADPCM;					    }					  else					    {					      if (match_four_chars((unsigned char *)(hdrbuf + 26), I_in32))						data_format = MUS_BINT;					      else						{						  if (match_four_chars((unsigned char *)(hdrbuf + 26), I_in24))						    data_format = MUS_B24INT;						  else						    {						      /* others from Sound.h:							 0x6D730002, -- Microsoft ADPCM - ACM code 2							 0x6D730011, -- DVI/Intel IMA ADPCM - ACM code 17							 'MAC3' -- MACE 3:1							 'MAC6' -- MACE 6:1							 'cdx4' -- CD/XA 4:1							 'cdx2' -- CD/XA 2:1							 'dvca' -- DV Audio							 'QDMC' -- QDesign music							 'QDM2' -- QDesign2 music							 'Qclp' -- QUALCOMM PureVoice							 0x6D730055 -- MPEG Layer 3, CBR only (pre QT4.1)							 '.mp3' -- MPEG Layer 3, CBR & VBR (QT4.1 and later)						      */						      data_format = MUS_UNKNOWN;						    }						}					    }					}				    }				}			    }			}		    }		}	    }	  data_size = (frames * mus_bytes_per_sample(data_format) * chans);	}      else	{	  if (match_four_chars((unsigned char *)hdrbuf, I_SSND))	    {	      if (data_location != 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: two SSND chunks found", filename));	      update_ssnd_location = offset + 4;	      data_location = mus_char_to_bint((unsigned char *)(hdrbuf + 8)) + offset + 16; /* Baroque! */	      /* offset is where the hdrbuf is positioned in the file, the sound data offset itself is at loc+8 and the */	      /* 0-based location of the sound data is at the end of the chunk = 16 (8 = header+4 = offset+4 = blocksize) */	      /* the next int can be the block size if the data is block-aligned */	      /* only one SSND per AIFF is allowed */	      if (chunksize == 0) break; /* this may happen while pre-reading an in-progress output file for updating */	      ssnd_bytes = offset + chunksize - data_location + 8;	    }	  else	    {	      if ((match_four_chars((unsigned char *)hdrbuf, I_ANNO)) || 		  (match_four_chars((unsigned char *)hdrbuf, I_COMT)) ||		  (match_four_chars((unsigned char *)hdrbuf, I_NAME)) ||		  (match_four_chars((unsigned char *)hdrbuf, I_AUTH)))		{		  j = 0;		  for (i = 0; i < AUX_COMMENTS; i++) 		    if (aux_comment_start[i] == 0) 		      {			j = i; 			break;		      }		  if (j >= AUX_COMMENTS) 		    {		      mus_print("read_aiff_header: ran out of auxiliary comment space");		      j = 0;		    }		  aux_comment_start[j] = offset + 8;		  if (match_four_chars((unsigned char *)hdrbuf, I_COMT)) 		    aux_comment_start[j] += 8; /* skip time stamp and markerId (not ID, I assume!) */		  aux_comment_end[j] = offset + 7 + chunksize;		}	      else		{		  if (match_four_chars((unsigned char *)hdrbuf, I_APPL))		    {		      if (match_four_chars((unsigned char *)(hdrbuf + 8), I_MUS_))			{			  /* my own chunk has the arbitrary length comment I use (actually the ASCII    */			  /* representation of a lisp program evaluated in the CLM package) to handle mix et al. */			  /* It is nothing more than the actual string -- remember to pad to even length here. */			  comment_start = offset + 12;

⌨️ 快捷键说明

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