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

📄 alsa_a.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 3 页
字号:
  ret = snd_pcm_close (handle);  if (ret < 0 && ret != -EINVAL) /* Maybe alsa-driver 0.5 has a bug */    error_report (ret);  handle = NULL;  dpm.fd = -1;}static int output_data(char *buf, int32 nbytes){  int n;  snd_pcm_channel_status_t status;  if (! handle)    return -1;  n = snd_pcm_write (handle, buf, nbytes);  if (n <= 0)    {      memset (&status, 0, sizeof(status));      status.channel = SND_PCM_CHANNEL_PLAYBACK;      if (snd_pcm_channel_status(handle, &status) < 0)	{	  ctl->cmsg(CMSG_WARNING, VERB_DEBUG,		    "%s: could not get channel status", alsa_device_name());	  return -1;	}      if (status.status == SND_PCM_STATUS_UNDERRUN || n == -EPIPE)	{	  ctl->cmsg(CMSG_INFO, VERB_DEBUG,		    "%s: underrun at %d", alsa_device_name(), status.scount);	  output_counter += status.scount;	  snd_pcm_channel_flush (handle, SND_PCM_CHANNEL_PLAYBACK);	  snd_pcm_channel_prepare (handle, SND_PCM_CHANNEL_PLAYBACK);	  n = snd_pcm_write (handle, buf, nbytes);	}      if (n <= 0)	{	  ctl->cmsg(CMSG_WARNING, VERB_DEBUG,		    "%s: %s", alsa_device_name(),		    (n < 0) ? snd_strerror(n) : "write error");	  if (n != -EPIPE)  /* buffer underrun is ignored */	    return -1;	}    }  return 0;}static int acntl(int request, void *arg){  int i;  snd_pcm_channel_status_t pstatus;  memset (&pstatus, 0, sizeof (pstatus));  pstatus.channel = SND_PCM_CHANNEL_PLAYBACK;  if (handle == NULL)    return -1;  switch (request)    {      case PM_REQ_GETFRAGSIZ:	if (frag_size == 0)	  return -1;	*((int *)arg) = frag_size;	return 0;      case PM_REQ_GETQSIZ:	if (total_bytes == -1)	  return -1;	*((int *)arg) = total_bytes;	return 0;      case PM_REQ_GETFILLABLE:	if (total_bytes == -1)	  return -1;	if (snd_pcm_channel_status(handle, &pstatus) < 0)	  return -1;	i = pstatus.free >> sample_shift;	*((int *)arg) = i;	return 0;      case PM_REQ_GETFILLED:	if (total_bytes == -1)	  return -1;	if (snd_pcm_channel_status(handle, &pstatus) < 0)	  return -1;	i = pstatus.count >> sample_shift;	*((int *)arg) = i;	return 0;      case PM_REQ_GETSAMPLES:	if (total_bytes == -1)	  return -1;	if (snd_pcm_channel_status(handle, &pstatus) < 0)	  return -1;	i = (output_counter + pstatus.scount) >> sample_shift;	*((int *)arg) = i;	return 0;      case PM_REQ_DISCARD:	if (snd_pcm_playback_drain(handle) < 0)	  return -1;	if (snd_pcm_channel_prepare(handle, SND_PCM_CHANNEL_PLAYBACK) < 0)	  return -1;	output_counter = 0;	return 0;      case PM_REQ_FLUSH:	if (snd_pcm_channel_flush(handle, SND_PCM_CHANNEL_PLAYBACK) < 0)	  return -1;	if (snd_pcm_channel_prepare(handle, SND_PCM_CHANNEL_PLAYBACK) < 0)	  return -1;	output_counter = 0;	return 0;    }    return -1;}/* end ALSA API 0.5.x */#elif ALSA_LIB < 5/*================================================================ * ALSA API version 0.4.x *================================================================*//*return value == 0 sucess               == 1 warning               == -1 fails */static int set_playback_info (snd_pcm_t* handle__,			      int32* encoding__, int32* rate__,			      const int32 extra_param[5]){  int ret_val = 0;  const int32 orig_encoding = *encoding__;  const int32 orig_rate = *rate__;  int tmp;  snd_pcm_playback_info_t pinfo;  snd_pcm_format_t pcm_format;  struct snd_pcm_playback_params pparams;  struct snd_pcm_playback_status pstatus;  memset (&pcm_format, 0, sizeof (pcm_format));  memset (&pinfo, 0, sizeof (pinfo));  memset (&pparams, 0, sizeof (pparams));  tmp = snd_pcm_playback_info (handle__, &pinfo);  if (tmp < 0)    {      error_report (tmp);      return -1;    }  /*check sample bit*/  if ((pinfo.flags & SND_PCM_PINFO_8BITONLY) != 0)    *encoding__ &= ~PE_16BIT; /*force 8bit samples*/  if ((pinfo.flags & SND_PCM_PINFO_16BITONLY) != 0)    *encoding__ |= PE_16BIT; /*force 16bit samples*/  /*check rate*/  if (pinfo.min_rate > *rate__)    *rate__ = pinfo.min_rate;  if (pinfo.max_rate < *rate__)    *rate__ = pinfo.max_rate;  pcm_format.rate = *rate__;  /*check channels*/  if ((*encoding__ & PE_MONO) != 0 && pinfo.min_channels > 1)    *encoding__ &= ~PE_MONO;  if ((*encoding__ & PE_MONO) == 0 && pinfo.max_channels < 2)    *encoding__ |= PE_MONO;  if ((*encoding__ & PE_MONO) != 0)    pcm_format.channels = 1; /*mono*/  else    pcm_format.channels = 2; /*stereo*/  /*check format*/  if ((*encoding__ & PE_16BIT) != 0)    { /*16bit*/      if ((pinfo.formats & SND_PCM_FMT_S16_LE) != 0)	{	  pcm_format.format = SND_PCM_SFMT_S16_LE;	  *encoding__ |= PE_SIGNED;	}      else	{	  ctl->cmsg(CMSG_ERROR, VERB_NORMAL,		    "%s doesn't support 16 bit sample width",		    alsa_device_name());	  return -1;	}    }  else    { /*8bit*/      if ((pinfo.formats & SND_PCM_FMT_U8) != 0)	{	  pcm_format.format = SND_PCM_SFMT_U8;	  *encoding__ &= ~PE_SIGNED;	}#if 0      else if ((pinfo.formats & SND_PCM_FMT_S8) != 0)	{	  pcm_format.format = SND_PCM_SFMT_U16_LE;	  *encoding__ |= PE_SIGNED;	}#endif      else	{	  ctl->cmsg(CMSG_ERROR, VERB_NORMAL,		    "%s doesn't support 8 bit sample width",		    alsa_device_name());	  return -1;	}    }  tmp = snd_pcm_playback_format (handle__, &pcm_format);  if (tmp < 0)    {      error_report (tmp);      return -1;    }  /*check result of snd_pcm_playback_format*/  if ((*encoding__ & PE_16BIT) != (orig_encoding & PE_16BIT ))    {      ctl->cmsg (CMSG_WARNING, VERB_VERBOSE,		 "Sample width adjusted to %d bits",		 ((*encoding__ & PE_16BIT) != 0)? 16:8);      ret_val = 1;    }  if (((pcm_format.channels == 1)? PE_MONO:0) != (orig_encoding & PE_MONO))    {      ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Sound adjusted to %sphonic",		((*encoding__ & PE_MONO) != 0)? "mono" : "stereo");      ret_val = 1;    }  sample_shift = 0;  if (!(dpm.encoding & PE_MONO))    sample_shift++;  if (dpm.encoding & PE_16BIT)    sample_shift++;  /* Set buffer fragment size (in extra_param[1]) */  if (extra_param[1] != 0)    tmp = extra_param[1];  else    tmp = audio_buffer_size << sample_shift;  /* Set buffer fragments (in extra_param[0]) */  pparams.fragment_size  = tmp;  pparams.fragments_max  = (extra_param[0] == 0) ? -1 : extra_param[0];  pparams.fragments_room = 1;  tmp = snd_pcm_playback_params (handle__, &pparams);  if (tmp < 0)    {      ctl->cmsg(CMSG_WARNING, VERB_NORMAL,		"%s doesn't support buffer fragments"		":request size=%d, max=%d, room=%d\n",		alsa_device_name(),		pparams.fragment_size,		pparams.fragments_max,		pparams.fragments_room);      ret_val = 1;    }  if (snd_pcm_playback_status(handle__, &pstatus) == 0)    {      if (pstatus.rate != orig_rate)	{	  ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,		    "Output rate adjusted to %d Hz (requested %d Hz)",		    pstatus.rate, orig_rate);	  dpm.rate = pstatus.rate;	  ret_val = 1;	}      frag_size = pstatus.fragment_size;      total_bytes = pstatus.count;    }  else    {      frag_size = 0;      total_bytes = -1; /* snd_pcm_playback_status fails */    }  return ret_val;}static int open_output(void){  int tmp, warnings=0;  int ret;  tmp = check_sound_cards (&card, &device, dpm.extra_param);  if (tmp < 0)    return -1;  /* Open the audio device */  ret = snd_pcm_open (&handle, card, device, SND_PCM_OPEN_PLAYBACK);  if (ret < 0)    {      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",		alsa_device_name(), snd_strerror (ret));      return -1;    }  /* They can't mean these */  dpm.encoding &= ~(PE_ULAW|PE_ALAW|PE_BYTESWAP);  warnings = set_playback_info (handle, &dpm.encoding, &dpm.rate,				dpm.extra_param);  if (warnings < 0)    {      close_output ();      return -1;    }  dpm.fd = snd_pcm_file_descriptor (handle);  output_counter = 0;  return warnings;}static void close_output(void){  int ret;  if (handle == NULL)    return;  ret = snd_pcm_close (handle);  if (ret < 0)    error_report (ret);  handle = NULL;  dpm.fd = -1;}static int output_data(char *buf, int32 nbytes){  int n;  if (! handle)    return -1;  while (nbytes > 0)    {      n = snd_pcm_write (handle, buf, nbytes);      if (n < 0)        {	  ctl->cmsg(CMSG_WARNING, VERB_DEBUG,		    "%s: %s", alsa_device_name(), snd_strerror(n));	  if (n == -EWOULDBLOCK)	    continue;	  return -1;	}      buf += n;      nbytes -= n;      output_counter += n;    }  return 0;}static int acntl(int request, void *arg){  int i;  struct snd_pcm_playback_status pstatus;  if (handle == NULL)    return -1;  switch (request)    {      case PM_REQ_GETFRAGSIZ:	if (frag_size == 0)	  return -1;	*((int *)arg) = frag_size;	return 0;      case PM_REQ_GETQSIZ:	if (total_bytes == -1)	  return -1;	*((int *)arg) = total_bytes;	return 0;      case PM_REQ_GETFILLABLE:	if (total_bytes == -1)	  return -1;	if (snd_pcm_playback_status(handle, &pstatus) < 0)	  return -1;	i = pstatus.count >> sample_shift;	*((int *)arg) = i;	return 0;      case PM_REQ_GETFILLED:	if (total_bytes == -1)	  return -1;	if (snd_pcm_playback_status(handle, &pstatus) < 0)	  return -1;	i = pstatus.queue >> sample_shift;	*((int *)arg) = i;	return 0;      case PM_REQ_GETSAMPLES:	if (total_bytes == -1)	  return -1;	if (snd_pcm_playback_status(handle, &pstatus) < 0)	  return -1;	i = output_counter - pstatus.queue;	i >>= sample_shift;	*((int *)arg) = i;	return 0;      case PM_REQ_DISCARD:	if (snd_pcm_drain_playback (handle) < 0)	  return -1; /* error */	output_counter = 0;	return 0;      case PM_REQ_FLUSH:	if (snd_pcm_flush_playback(handle) < 0)	  return -1; /* error */	output_counter = 0;	return 0;    }    return -1;}/* end ALSA API 0.4.x */#endif

⌨️ 快捷键说明

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