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

📄 audio.c

📁 音频信号的重采样程序,如44.1K的WAV转换成采样频率为48K的WAV.
💻 C
📖 第 1 页 / 共 5 页
字号:
	      status = ioctl(fd, OSS_SYSINFO, &sysinfo);	      sysinfo_ok = (status == 0);	    }	  if ((new_oss_running) && (sysinfo_ok))	    {	      num_mixers = sysinfo.nummixers;	      num_dsps = sysinfo.numaudios;	    }	  close(fd);	}#endif      /* need to get which /dev/dsp lines match which /dev/mixer lines,       *   find out how many separate systems (soundcards) are available,       *   fill the audio_dsp and audio_mixer arrays with the system-related numbers,       * since we have no way to tell from OSS info which mixers/dsps are the       *   main ones, we'll do some messing aound to try to deduce this info.       * for example, SB uses two dsp ports and two mixers per card, whereas       *  Ensoniq uses 2 dsps and 1 mixer.       *        * the data we are gathering here:       *   int audio_dsp[MAX_SOUNDCARDS] -> main_dsp_port[MUS_AUDIO_PACK_SYSTEM(n)] (-1 => no such system dsp)       *   int audio_mixer[MAX_SOUNDCARDS] -> main_mixer_port[MUS_AUDIO_PACK_SYSTEM(n)]       *   int sound_cards = 0 -> usable systems       * all auxiliary ports are currently ignored (SB equalizer, etc)       */      sound_cards = 0;      ndsp = 0;      nmix = 0;      while ((nmix < num_mixers) && 	     (ndsp < num_dsps))	{	  /* for each mixer, find associated main dsp (assumed to be first in /dev/dsp ordering) */	  /*   if mixer's dsp overlaps or we run out of dsps first, ignore it (aux mixer) */	  /* our by-guess-or-by-gosh method here is to try to open the mixer.	   *   if that fails, quit (if very first, try at least to get the dsp setup)	   *   find volume field, if none, go on, else read current volume	   *   open next unchecked dsp, try to set volume, read current, if different we found a match -- set and go on.	   *     if no change, move to next dsp and try again, if no more dsps, quit (checking for null case as before)	   */	  mus_snprintf(dname, LABEL_BUFFER_SIZE, "%s%d", MIXER_NAME, nmix);	  md = open(dname, O_RDWR, 0);	  if (md == -1)	    {	      if (errno == EBUSY) 		{		  mus_print("%s is busy: can't access it [%s[%d] %s]", 			    dname,			    __FILE__, __LINE__, c__FUNCTION__); 		  nmix++;		  continue;		}	      else break;	    }	  mus_snprintf(dname, LABEL_BUFFER_SIZE, "%s%d", DAC_NAME, ndsp);	  fd = open(dname, O_RDWR | O_NONBLOCK, 0);	  if (fd == -1) fd = open(dname, O_RDONLY | O_NONBLOCK, 0); 	  if (fd == -1) fd = open(dname, O_WRONLY | O_NONBLOCK, 0); /* some output devices need this */	  if (fd == -1)	    {	      close(md); 	      if (errno == EBUSY) /* in linux /usr/include/asm/errno.h */		{		  fprintf(stderr, "%s is busy: can't access it\n", dname); 		  ndsp++;		  continue;		}	      else 		{		  if ((errno != ENXIO) && (errno != ENODEV))		    fprintf(stderr, "%s: %s! ", dname, strerror(errno));		  break;		}	    }#ifdef NEW_OSS				  	  /* can't change volume yet of Sonorus, so the method above won't work --	   * try to catch this case via the mixer's name	   */	  status = ioctl(md, SOUND_MIXER_INFO, &mixinfo);	  if ((status == 0) && 	      (mixinfo.name) && 	      (*(mixinfo.name)) && 	      (strlen(mixinfo.name) > 6))	    {	      if (strncmp("STUDI/O", mixinfo.name, 7) == 0)		{		  /* a special case in every regard */		  audio_type[sound_cards] = SONORUS_STUDIO;		  audio_mixer[sound_cards] = nmix; 		  nmix++;		  audio_dsp[sound_cards] = ndsp; 		  if (num_dsps >= 21)		    {		      ndsp += 21;		      audio_mode[sound_cards] = 1;		    }		  else		    {		      ndsp += 9;		      audio_mode[sound_cards] = 0;		    }		  sound_cards++;		  close(fd);		  close(md);		  continue;		}	      else		{		  if (strncmp("RME Digi96", mixinfo.name, 10) == 0)		    {		      audio_type[sound_cards] = RME_HAMMERFALL;		      audio_mixer[sound_cards] = nmix; 		      nmix++;		      audio_dsp[sound_cards] = ndsp; 		      sound_cards++;		      close(fd);		      close(md);		      continue;		    }		  else		    {		      if (strncmp("M Audio Delta", mixinfo.name, 13) == 0)			{			  audio_type[sound_cards] = DELTA_66;			  audio_mixer[sound_cards] = nmix; 			  nmix++;			  ndsp += 6; /* just a guess */			  audio_dsp[sound_cards] = ndsp; 			  sound_cards++;			  close(fd);			  close(md);			  continue;			}		    }		}	    }#endif	  err = ioctl(md, SOUND_MIXER_READ_DEVMASK, &devmask);	  responsive_field = SOUND_MIXER_VOLUME;	  for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)	    if ((1 << i) & devmask)	      {		responsive_field = i;		break;	      }	  if (!err)	    {	      err = ioctl(md, MIXER_READ(responsive_field), &old_mixer_amp);	      if (!err)		{		  err = ioctl(fd, MIXER_READ(responsive_field), &old_dsp_amp);		  if ((!err) && (old_dsp_amp == old_mixer_amp))		    {		      if (old_mixer_amp == 0) amp = 50; else amp = 0; /* 0..100 */		      err = ioctl(fd, MIXER_WRITE(responsive_field), &amp);		      if (!err)			{			  err = ioctl(md, MIXER_READ(responsive_field), &new_mixer_amp);			  if (!err)			    {			      if (new_mixer_amp == amp)				{				  /* found one! */				  audio_dsp[sound_cards] = ndsp; ndsp++;				  audio_mixer[sound_cards] = nmix; nmix++;				    audio_type[sound_cards] = NORMAL_CARD;				  sound_cards++;				}			      else ndsp++;			      err = ioctl(fd, MIXER_WRITE(responsive_field), &old_dsp_amp);			    }			  else nmix++;			}		      else ndsp++;		    }		  else ndsp++;		}	      else nmix++;	    }	  else nmix++;	  close(fd);	  close(md);	}      if (sound_cards == 0)	{ 	  fd = open(DAC_NAME, O_WRONLY | O_NONBLOCK, 0);	  if (fd != -1)	    {	      sound_cards = 1;	      audio_dsp[0] = 0;	      audio_type[0] = NORMAL_CARD;	      audio_mixer[0] = -2; /* hmmm -- need a way to see /dev/dsp as lonely outpost */	      close(fd); 	      fd = open(MIXER_NAME, O_RDONLY | O_NONBLOCK, 0);	      if (fd == -1)		audio_mixer[0] = -3;	      else close(fd);	    }	}    }  return(MUS_NO_ERROR);}int mus_audio_reinitialize(void){  /* an experiment */  audio_initialized = false;  return(mus_audio_initialize());}static int linux_audio_open(const char *pathname, int flags, mode_t mode, int system){  /* sometimes this is simply searching for a device (so failure is not a mus_error) */  if (audio_fd[system] == -1)     {      audio_fd[system] = open(pathname, flags, mode);      audio_open_ctr[system] = 0;    }  else audio_open_ctr[system]++;  return(audio_fd[system]);}static int linux_audio_open_with_error(const char *pathname, int flags, mode_t mode, int system){  int fd;  fd = linux_audio_open(pathname, flags, mode, system);  if (fd == -1)    MUS_STANDARD_IO_ERROR(MUS_AUDIO_CANT_OPEN,			  ((mode == O_RDONLY) ? "open read" : 			   (mode == O_WRONLY) ? "open write" : "open read/write"),			  pathname);  return(fd);}static int find_system(int line){  int i;  for (i = 0; i < sound_cards; i++)    if (line == audio_fd[i])      return(i);  return(MUS_ERROR);}static int linux_audio_close(int fd){  if (fd != -1)    {      int err = 0, sys;      sys = find_system(fd);      if (sys != -1)	{	  if (audio_open_ctr[sys] > 0) 	    audio_open_ctr[sys]--;	  else 	    {	      err = close(fd);	      audio_open_ctr[sys] = 0;	      audio_fd[sys] = -1;	    }	}      else err = close(fd);      if (err) RETURN_ERROR_EXIT(MUS_AUDIO_CANT_CLOSE, -1,				 mus_format("close %d failed: %s",					    fd, strerror(errno)));    }  /* is this an error? */  return(MUS_NO_ERROR);}static int to_oss_format(int snd_format){  switch (snd_format)    {    case MUS_BYTE:    return(AFMT_S8);     break;    case MUS_BSHORT:  return(AFMT_S16_BE); break;    case MUS_UBYTE:   return(AFMT_U8);     break;    case MUS_MULAW:   return(AFMT_MU_LAW); break;    case MUS_ALAW:    return(AFMT_A_LAW);  break;    case MUS_LSHORT:  return(AFMT_S16_LE); break;    case MUS_UBSHORT: return(AFMT_U16_BE); break;    case MUS_ULSHORT: return(AFMT_U16_LE); break;#ifdef NEW_OSS    case MUS_LINT:    return(AFMT_S32_LE); break;    case MUS_BINT:    return(AFMT_S32_BE); break;#endif    }  return(MUS_ERROR);}static char sonorus_buf[LABEL_BUFFER_SIZE];static char *sonorus_name(int sys, int offset){  mus_snprintf(sonorus_buf, LABEL_BUFFER_SIZE, "/dev/dsp%d", offset + audio_dsp[sys]);  return(sonorus_buf);}static bool fragment_set_failed = false;static int oss_mus_audio_open_output(int ur_dev, int srate, int chans, int format, int size){  /* ur_dev is in general MUS_AUDIO_PACK_SYSTEM(n) | MUS_AUDIO_DEVICE */  int oss_format, buffer_info, audio_out = -1, sys, dev;  char *dev_name;#ifndef NEW_OSS  int stereo;#endif  sys = MUS_AUDIO_SYSTEM(ur_dev);  dev = MUS_AUDIO_DEVICE(ur_dev);  oss_format = to_oss_format(format);   if (oss_format == MUS_ERROR)     RETURN_ERROR_EXIT(MUS_AUDIO_FORMAT_NOT_AVAILABLE, -1,		      mus_format("format %d (%s) not available",				 format, 				 mus_data_format_name(format)));  if (audio_type[sys] == SONORUS_STUDIO)    {      /* in this case the output devices are parcelled out to the /dev/dsp locs */      /* dev/dsp0 is always stereo */      switch (dev)	{	case MUS_AUDIO_DEFAULT: 	  if (chans > 2) 	    audio_out = open(sonorus_name(sys, 1), O_WRONLY, 0);	  else audio_out = open(sonorus_name(sys, 0), O_WRONLY, 0);	  /* probably should write to both outputs */	  if (audio_out == -1) audio_out = open("/dev/dsp", O_WRONLY, 0);	  break;	case MUS_AUDIO_SPEAKERS:	  audio_out = open(sonorus_name(sys, 0), O_WRONLY, 0);	  if (audio_out == -1) audio_out = open("/dev/dsp", O_WRONLY, 0);	  break;	case MUS_AUDIO_ADAT_OUT: case MUS_AUDIO_SPDIF_OUT:	  audio_out = open(sonorus_name(sys, 1), O_WRONLY, 0);	  break;	case MUS_AUDIO_AES_OUT:	  audio_out = open(sonorus_name(sys, 9), O_WRONLY, 0);	  break;	default:	  RETURN_ERROR_EXIT(MUS_AUDIO_DEVICE_NOT_AVAILABLE, audio_out,			    mus_format("Sonorus device %d (%s) not available",				       dev, 				       mus_audio_device_name(dev)));	  break;	}      if (audio_out == -1) 	RETURN_ERROR_EXIT(MUS_AUDIO_CANT_OPEN, audio_out,			  mus_format("can't open Sonorus output device %d (%s): %s",				     dev, 				     mus_audio_device_name(dev), strerror(errno)));#ifdef NEW_OSS      if (ioctl(audio_out, SNDCTL_DSP_CHANNELS, &chans) == -1) 	RETURN_ERROR_EXIT(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, audio_out,			  mus_format("can't get %d channels for Sonorus device %d (%s)",				     chans, dev, 				     mus_audio_device_name(dev)));#endif      return(audio_out);    }#if HAVE_SAM_9407  if (audio_type[sys] == SAM9407_DSP)    {      char dname[LABEL_BUFFER_SIZE];      mus_snprintf(dname, LABEL_BUFFER_SIZE, "/dev/sam%d_dsp", audio_dsp[sys]);      audio_out = open(dname, O_WRONLY);      if(audio_out == -1)	RETURN_ERROR_EXIT(MUS_AUDIO_CANT_OPEN, audio_out,			  mus_format("can't open %s: %s",				     dname, 				     strerror(errno)));      if ((ioctl(audio_out, SNDCTL_DSP_SETFMT, &oss_format) == -1) || 	  (oss_format != to_oss_format(format))) 	RETURN_ERROR_EXIT(MUS_AUDIO_FORMAT_NOT_AVAILABLE, audio_out,			  mus_format("can't set %s format to %d (%s)",				     dname, format, 				     mus_data_format_name(format)));      if (ioctl(audio_out, SNDCTL_DSP_CHANNELS, &chans) == -1)	RETURN_ERROR_EXIT(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, audio_out,			  mus_format("can't get %d channels on %s",				     chans, dname));      if (ioctl(audio_out, SNDCTL_DSP_SPEED, &srate) == -1)	RETURN_ERROR_EXIT(MUS_AUDIO_SRATE_NOT_AVAILABLE, audio_out,			  mus_format("can't set srate to %d on %s",				     srate, dname));      FRAGMENT_SIZE = 14;      buffer_info = (FRAGMENTS << 16) | (FRAGMENT_SIZE);      ioctl(audio_out, SNDCTL_DSP_SETFRAGMENT, &buffer_info);      return(audio_out);    }#endif  if (dev == MUS_AUDIO_DEFAULT)    audio_out = linux_audio_open_with_error(dev_name = dac_name(sys, 0), 					    O_WRONLY, 0, sys);  else audio_out = linux_audio_open_with_error(dev_name = dac_nam

⌨️ 快捷键说明

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