Exemple #1
0
static snd_pcm_t *open_audiofd( char *device_name, int capture, int rate, int channels, int period, int nperiods ) {
  int err;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *hwparams;
  snd_pcm_sw_params_t *swparams;

  snd_pcm_hw_params_alloca(&hwparams);
  snd_pcm_sw_params_alloca(&swparams);

  if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) {
      printf("Capture open error: %s\n", snd_strerror(err));
      return NULL;
  }

  if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) {
      printf("Setting of hwparams failed: %s\n", snd_strerror(err));
      return NULL;
  }
  if ((err = set_swparams(handle, swparams, period, nperiods)) < 0) {
      printf("Setting of swparams failed: %s\n", snd_strerror(err));
      return NULL;
  }

  //snd_pcm_start( handle );
  //snd_pcm_wait( handle, 200 );
  int num_null_samples = nperiods * period * channels;
  char *tmp = alloca( num_null_samples * formats[format].sample_size ); 
  memset( tmp, 0, num_null_samples * formats[format].sample_size );
  snd_pcm_writei( handle, tmp, num_null_samples );
  

  return handle;
}
int alsa_open( void )
{
  int err;

  snd_pcm_hw_params_t *hwparams;
  snd_pcm_sw_params_t *swparams;

  DEBUGLOG("alsa_open\n");

  snd_pcm_hw_params_alloca(&hwparams);
  snd_pcm_sw_params_alloca(&swparams);

  if((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0/*SND_PCM_NONBLOCK*/)) < 0 ) {
    ERRORLOG("open failed: %s\n", snd_strerror(err));
    return -1;
  }

  if((err = set_hwparams(hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
    ERRORLOG("Setting of hwparams failed: %s\n", snd_strerror(err));
    return -1;
  }
  if((err = set_swparams(swparams)) < 0) {
    ERRORLOG("Setting of swparams failed: %s\n", snd_strerror(err));
    return -1;
  }

  return 0;
}
Exemple #3
0
/**********************************************************************************
* pcm_init()
*
***********************************************************************************/
static void pcm_init(void)
{
    int err;
    snd_pcm_hw_params_t *hwparams;
    snd_pcm_sw_params_t *swparams;
    snd_pcm_hw_params_alloca(&hwparams);
    snd_pcm_sw_params_alloca(&swparams);

    if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) 
    {
        printf("Playback open error: %s\n", snd_strerror(err));
    }
    if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) 
    {
        printf("Setting of hwparams failed: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    if ((err = set_swparams(handle, swparams)) < 0) 
    {
        printf("Setting of swparams failed: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }       
    /*分配空间 period的空间,period指向空间首地址*/
    period_size_real = period_size * channels * snd_pcm_format_physical_width(format) / 8;//snd_pcm_format_physical_width:return bits needed to store a PCM sample.
    period = malloc(period_size_real);
    if (period == NULL) 
    {
        printf("No enough memory\n");
        exit(EXIT_FAILURE);
    }
    fprintf(stdout,"pcm_init sucess !\n");
}
BOOL	alsa_open_audio(BOOL use_mmap) {
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_sw_params_t *swparams;
	int err;
	snd_pcm_access_t access = (use_mmap)?(SND_PCM_ACCESS_MMAP_INTERLEAVED)
		:(SND_PCM_ACCESS_RW_INTERLEAVED);
	format = (use_mmap)?(format_8):(format_16);

	if (alsa_audiodev_is_open) return TRUE;
	snd_pcm_hw_params_alloca(&hwparams);
	snd_pcm_sw_params_alloca(&swparams);

	err = snd_output_stdio_attach(&output, stdout, 0);
	if (err < 0) {
		printf("Output failed: %s\n", snd_strerror(err));
		return 0;
	}

	if ((err = snd_pcm_open(&playback_handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
		printf("Playback open error: %s\n", snd_strerror(err));
		return 0;
	}

	if ((err = set_hwparams(playback_handle, hwparams, access)) < 0) {
		printf("Setting of hwparams failed: %s\n", snd_strerror(err));
		return 0;
	}
	if ((err = set_swparams(playback_handle, swparams)) < 0) {
		printf("Setting of swparams failed: %s\n", snd_strerror(err));
		return 0;
	}
	snd_pcm_dump(playback_handle, output);

	samples = malloc((period_size * channels * snd_pcm_format_width(format)) / 8);
	if (samples == NULL) {
		printf("No enough memory\n");
		exit(EXIT_FAILURE);
	}

	areas = calloc(channels, sizeof(snd_pcm_channel_area_t));
	if (areas == NULL) {
		printf("No enough memory\n");
		exit(EXIT_FAILURE);
	}
	for (chn = 0; chn < channels; chn++) {
		areas[chn].addr = samples;
		areas[chn].first = chn * snd_pcm_format_width(format);
		areas[chn].step = channels * snd_pcm_format_width(format);
	}

	alsa_audiodev_is_open = TRUE;

	//err = snd_pcm_writei(playback_handle, samples, (period_size * channels * snd_pcm_format_width(format)) / 8);

	return TRUE;
}
Exemple #5
0
static gboolean
gst_alsasrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
{
  GstAlsaSrc *alsa;
  gint err;

  alsa = GST_ALSA_SRC (asrc);

  if (!alsasrc_parse_spec (alsa, spec))
    goto spec_parse;

  CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block);

  CHECK (set_hwparams (alsa), hw_params_failed);
  CHECK (set_swparams (alsa), sw_params_failed);
  CHECK (snd_pcm_prepare (alsa->handle), prepare_failed);

  alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info);
  spec->segsize = alsa->period_size * alsa->bpf;
  spec->segtotal = alsa->buffer_size / alsa->period_size;

  return TRUE;

  /* ERRORS */
spec_parse:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Error parsing spec"));
    return FALSE;
  }
non_block:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Could not set device to blocking: %s", snd_strerror (err)));
    return FALSE;
  }
hw_params_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Setting of hwparams failed: %s", snd_strerror (err)));
    return FALSE;
  }
sw_params_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Setting of swparams failed: %s", snd_strerror (err)));
    return FALSE;
  }
prepare_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Prepare failed: %s", snd_strerror (err)));
    return FALSE;
  }
}
Exemple #6
0
static gboolean
gst_alsasink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
{
    GstAlsaSink *alsa;
    gint err;

    alsa = GST_ALSA_SINK (asink);

    if (alsa->iec958) {
        snd_pcm_close (alsa->handle);
        alsa->handle = gst_alsa_open_iec958_pcm (GST_OBJECT (alsa), alsa->device);
        if (G_UNLIKELY (!alsa->handle)) {
            goto no_iec958;
        }
    }

    if (!alsasink_parse_spec (alsa, spec))
        goto spec_parse;

    CHECK (set_hwparams (alsa), hw_params_failed);
    CHECK (set_swparams (alsa), sw_params_failed);

    alsa->bytes_per_sample = spec->bytes_per_sample;
    spec->segsize = alsa->period_size * spec->bytes_per_sample;
    spec->segtotal = alsa->buffer_size / alsa->period_size;

    {
        snd_output_t *out_buf = NULL;
        char *msg = NULL;

        snd_output_buffer_open (&out_buf);
        snd_pcm_dump_hw_setup (alsa->handle, out_buf);
        snd_output_buffer_string (out_buf, &msg);
        GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg);
        snd_output_close (out_buf);
        snd_output_buffer_open (&out_buf);
        snd_pcm_dump_sw_setup (alsa->handle, out_buf);
        snd_output_buffer_string (out_buf, &msg);
        GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg);
        snd_output_close (out_buf);
    }

    return TRUE;

    /* ERRORS */
no_iec958:
    {
        GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_WRITE, (NULL),
                           ("Could not open IEC958 (SPDIF) device for playback"));
        return FALSE;
    }
spec_parse:
    {
        GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
                           ("Error parsing spec"));
        return FALSE;
    }
hw_params_failed:
    {
        GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
                           ("Setting of hwparams failed: %s", snd_strerror (err)));
        return FALSE;
    }
sw_params_failed:
    {
        GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
                           ("Setting of swparams failed: %s", snd_strerror (err)));
        return FALSE;
    }
}
Exemple #7
0
int alsamm_open_audio(int rate, int blocksize)
{
  int err;
  char devname[80];
  char *cardname;
  snd_pcm_hw_params_t* hw_params;
  snd_pcm_sw_params_t* sw_params;


  /* fragsize is an old concept now use periods, used to be called fragments. */
  /* Be aware in ALSA periodsize can be in bytes, where buffersize is in frames,
     but sometimes buffersize is in bytes and periods in frames, crazy alsa...
     ...we use periodsize and buffersize in frames */

  int i;
  short* tmp_buf;
  unsigned int tmp_uint;

  snd_pcm_hw_params_alloca(&hw_params);
  snd_pcm_sw_params_alloca(&sw_params);

  /* see add_devname */
  /* first have a look which cards we can get and
     set up device infos for them */

#ifdef ALSAMM_DEBUG
  if(sys_verbose)
    post("naudioindev=%d,  nchindev=%d, naudiooutdev=%d, nchoutdev=%d,rate=%d",
         naudioindev, nchindev,naudiooutdev, nchoutdev, rate);
#endif

  /* init some structures */
  for(i=0;i < ALSA_MAXDEV;i++){
    alsa_indev[i].a_synced=alsa_outdev[i].a_synced=0;
    alsa_indev[i].a_channels=alsa_outdev[i].a_channels=-1; /* query defaults */
  }
  alsamm_inchannels = 0;
  alsamm_outchannels = 0;

  /* opening alsa debug channel */
  err = snd_output_stdio_attach(&alsa_stdout, stdout, 0);
  if (err < 0) {
    check_error(err,"attaching alsa debug Output to stdout failed");
    /*    return; no so bad ... and never should happe */
  }


  /*
     Weak failure prevention:
     first card found (out then in) is used as a reference for parameter,
     so this  set the globals and other cards hopefully don't change them
  */
  alsamm_sr = rate;

  /* set the asked buffer time (alsa buffertime in us)*/
  alsamm_buffertime = alsamm_buffersize = 0;
  if(blocksize == 0)
    alsamm_buffertime = sys_schedadvance;
  else
    alsamm_buffersize = blocksize;

  if(sys_verbose)
    post("syschedadvance=%d us(%d Samples)so buffertime max should be this=%d"
         "or sys_blocksize=%d (samples) to use buffersize=%d",
         sys_schedadvance,sys_advance_samples,alsamm_buffertime,
         blocksize,alsamm_buffersize);

  alsamm_periods = 0; /* no one wants periods setting from command line ;-) */

  for(i=0;i<alsa_noutdev;i++)
  {
        /*   post("open audio out %d, of %lx, %d",i,&alsa_device[i],
                   alsa_outdev[i].a_handle); */
      if((err = set_hwparams(alsa_outdev[i].a_handle, hw_params,
                             &(alsa_outdev[i].a_channels))) < 0)
        {
          check_error(err,"playback device hwparam_set error:");
          continue;
        }

      if((err = set_swparams(alsa_outdev[i].a_handle, sw_params,1)) < 0){
        check_error(err,"playback device swparam_set error:");
        continue;
      }

      alsamm_outchannels += alsa_outdev[i].a_channels;

      alsa_outdev[i].a_addr =
        (char **) malloc(sizeof(char *) *  alsa_outdev[i].a_channels);

      if(alsa_outdev[i].a_addr == NULL){
        check_error(errno,"playback device outaddr allocation error:");
        continue;
      }
      memset(alsa_outdev[i].a_addr, 0, sizeof(char*) * alsa_outdev[i].a_channels);

      post("playback device with %d channels and buffer_time %d us opened",
           alsa_outdev[i].a_channels, alsamm_buffertime);
    }


  for(i=0;i<alsa_nindev;i++)
    {

      if(sys_verbose)
        post("capture card %d:--------------------",i);

      if((err = set_hwparams(alsa_indev[i].a_handle, hw_params,
                               &(alsa_indev[i].a_channels))) < 0)
        {
          check_error(err,"capture device hwparam_set error:");
          continue;
        }

      alsamm_inchannels += alsa_indev[i].a_channels;

      if((err = set_swparams(alsa_indev[i].a_handle,
            sw_params,0)) < 0){
        check_error(err,"capture device swparam_set error:");
        continue;
      }

      alsa_indev[i].a_addr =
        (char **) malloc (sizeof(char*) *  alsa_indev[i].a_channels);

      if(alsa_indev[i].a_addr == NULL){
        check_error(errno,"capture device inaddr allocation error:");
        continue;
      }

      memset(alsa_indev[i].a_addr, 0, sizeof(char*) * alsa_indev[i].a_channels);

      if(sys_verbose)
        post("capture device with %d channels and buffertime %d us opened\n",
             alsa_indev[i].a_channels,alsamm_buffertime);
    }

  /* check for linked handles of input for each output*/

  for(i=0; i<(alsa_noutdev < alsa_nindev ? alsa_noutdev:alsa_nindev); i++){
    t_alsa_dev *ad = &alsa_outdev[i];

    if (alsa_outdev[i].a_devno == alsa_indev[i].a_devno){
      if ((err = snd_pcm_link (alsa_indev[i].a_handle,
                               alsa_outdev[i].a_handle)) == 0){
        alsa_indev[i].a_synced = alsa_outdev[i].a_synced = 1;
        if(sys_verbose)
          post("Linking in and outs of card %d",i);
      }
      else
        check_error(err,"could not link in and outs");
    }
  }

  /* some globals */
  sleep_time =  (float) alsamm_period_size/ (float) alsamm_sr;


#ifdef ALSAMM_DEBUG
  /* start ---------------------------- */
  if(sys_verbose)
    post("open_audio: after dacsend=%d (xruns=%d)done",dac_send,alsamm_xruns);
  alsamm_xruns = dac_send = 0; /* reset debug */

  /* start alsa in open or better in send_dacs once ??? we will see */

  for(i=0;i<alsa_noutdev;i++)
    snd_pcm_dump(alsa_outdev[i].a_handle, alsa_stdout);

  for(i=0;i<alsa_nindev;i++)
    snd_pcm_dump(alsa_indev[i].inhandle, alsa_stdout);

  fflush(stdout);
#endif

  sys_setchsr(alsamm_inchannels,  alsamm_outchannels, alsamm_sr);

  alsamm_start();

  /* report success  */
  return (0);
}
static gboolean
gst_alsasrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
{
  GstAlsaSrc *alsa;
  gint err;

  alsa = GST_ALSA_SRC (asrc);

  if (!alsasrc_parse_spec (alsa, spec))
    goto spec_parse;

  CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block);

  CHECK (set_hwparams (alsa), hw_params_failed);
  CHECK (set_swparams (alsa), sw_params_failed);
  CHECK (snd_pcm_prepare (alsa->handle), prepare_failed);

  alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info);
  spec->segsize = alsa->period_size * alsa->bpf;
  spec->segtotal = alsa->buffer_size / alsa->period_size;

  {
    snd_output_t *out_buf = NULL;
    char *msg = NULL;

    snd_output_buffer_open (&out_buf);
    snd_pcm_dump_hw_setup (alsa->handle, out_buf);
    snd_output_buffer_string (out_buf, &msg);
    GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg);
    snd_output_close (out_buf);
    snd_output_buffer_open (&out_buf);
    snd_pcm_dump_sw_setup (alsa->handle, out_buf);
    snd_output_buffer_string (out_buf, &msg);
    GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg);
    snd_output_close (out_buf);
  }

#ifdef SND_CHMAP_API_VERSION
  if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) {
    snd_pcm_chmap_t *chmap = snd_pcm_get_chmap (alsa->handle);
    if (chmap && chmap->channels == alsa->channels) {
      GstAudioChannelPosition pos[8];
      if (alsa_chmap_to_channel_positions (chmap, pos))
        gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC
            (alsa)->ringbuffer, pos);
    }
    free (chmap);
  }
#endif /* SND_CHMAP_API_VERSION */

  return TRUE;

  /* ERRORS */
spec_parse:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Error parsing spec"));
    return FALSE;
  }
non_block:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Could not set device to blocking: %s", snd_strerror (err)));
    return FALSE;
  }
hw_params_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Setting of hwparams failed: %s", snd_strerror (err)));
    return FALSE;
  }
sw_params_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Setting of swparams failed: %s", snd_strerror (err)));
    return FALSE;
  }
prepare_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Prepare failed: %s", snd_strerror (err)));
    return FALSE;
  }
}
Exemple #9
0
static BOOL ALSA_Init_internal(void)
{
	snd_pcm_format_t pformat;
#ifdef OLD_ALSA
#define channels pformat.channels
#define rate pformat.rate
	int mask,card;
#else
    int rate;
    int channels;
    int err;
    snd_pcm_hw_params_t * hwparams;
	snd_pcm_sw_params_t * swparams;
#endif

	/* adjust user-configurable settings */
	if((getenv("MM_NUMFRAGS"))&&(numfrags==DEFAULT_NUMFRAGS)) {
		numfrags=atoi(getenv("MM_NUMFRAGS"));
		if ((numfrags<2)||(numfrags>16)) numfrags=DEFAULT_NUMFRAGS;
	}
#ifdef OLD_ALSA
	if((getenv("ALSA_CARD"))&&(!cardmin)&&(cardmax==SND_CARDS)) {
		cardmin=atoi(getenv("ALSA_CARD"));
		cardmax=cardmin+1;
#endif
		if(getenv("ALSA_PCM"))
			device=atoi(getenv("ALSA_PCM"));
#ifdef OLD_ALSA
	}
#endif

	/* setup playback format structure */
#define NUM_CHANNELS() ((md_mode&DMODE_STEREO)?2:1)

#ifdef OLD_ALSA
	memset(&pformat,0,sizeof(pformat));
#ifdef SND_LITTLE_ENDIAN
	pformat.format=(md_mode&DMODE_16BITS)?SND_PCM_SFMT_S16_LE:SND_PCM_SFMT_U8;
#else
	pformat.format=(md_mode&DMODE_16BITS)?SND_PCM_SFMT_S16_BE:SND_PCM_SFMT_U8;
#endif
#else
    pformat = (md_mode&DMODE_16BITS)?SND_PCM_FORMAT_S16_LE:SND_PCM_FORMAT_U8;
    snd_pcm_hw_params_alloca(&hwparams);
	snd_pcm_sw_params_alloca(&swparams);
#endif
	channels = NUM_CHANNELS();
	rate=md_mixfreq;

	/* scan for appropriate sound card */
#ifdef OLD_ALSA
	mask=alsa_cards_mask();
#endif
	_mm_errno=MMERR_OPENING_AUDIO;
#ifdef OLD_ALSA
	for (card=cardmin;card<cardmax;card++)
#endif
    {
#ifdef OLD_ALSA
		struct snd_ctl_hw_info info;
		snd_ctl_t *ctl_h;
		int dev,devmin,devmax;
#endif

#ifdef OLD_ALSA
		/* no card here, onto the next */
		if (!(mask&(1<<card))) continue;
#endif

#ifdef OLD_ALSA
		/* try to open the card in query mode */
		if (alsa_ctl_open(&ctl_h,card)<0)
			continue;
#else
        if ((err = alsa_pcm_open(&pcm_h, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0)) < 0)
        {
            printf("snd_pcm_open() call failed: %s\n", alsa_strerror(err));
            goto END;
        }
#endif

#ifdef OLD_ALSA
		/* get hardware information */
		if(alsa_ctl_hw_info(ctl_h,&info)<0) {
			alsa_ctl_close(ctl_h);
			continue;
		}

		/* scan subdevices */
		if(device==-1) {
			devmin=0;devmax=info.pcmdevs;
		} else
			devmin=devmax=device;
#endif

#ifdef OLD_ALSA
		for(dev=devmin;dev<devmax;dev++)
#endif
        {
#ifdef OLD_ALSA
			int size,bps;
			snd_pcm_info_t pcminfo;
			snd_pcm_playback_info_t ctlinfo;
			struct snd_pcm_playback_info pinfo;
			struct snd_pcm_playback_params pparams;

			/* get PCM capabilities */
			if(alsa_ctl_pcm_info(ctl_h,dev,&pcminfo)<0)
				continue;

			/* look for playback capability */
			if(!(pcminfo.flags&SND_PCM_INFO_PLAYBACK))
				continue;

			/* get playback information */
#if defined(SND_LIB_VERSION) && (SND_LIB_VERSION >= 0x400)
			if(alsa_ctl_pcm_playback_info(ctl_h,dev,0,&ctlinfo)<0)
				continue;
#else
			if(alsa_ctl_pcm_playback_info(ctl_h,dev,&ctlinfo)<0)
				continue;
#endif

	/*
	   If control goes here, we have found a sound device able to play PCM data.
	   Let's open in in playback mode and see if we have compatible playback
	   settings.
	*/

			if (alsa_pcm_open(&pcm_h,card,dev,SND_PCM_OPEN_PLAYBACK)<0)
				continue;

			if (alsa_pcm_playback_info(pcm_h,&pinfo)<0) {
				alsa_pcm_close(pcm_h);
				pcm_h=NULL;
				continue;
			}

			/* check we have compatible settings */
			if((pinfo.min_rate>rate)||(pinfo.max_rate<rate)||
			   (!(pinfo.formats&(1<<pformat.format)))) {
				alsa_pcm_close(pcm_h);
				pcm_h=NULL;
				continue;
			}

			fragmentsize=pinfo.buffer_size/numfrags;
#ifdef MIKMOD_DEBUG
			if ((fragmentsize<512)||(fragmentsize>16777216L))
				fprintf(stderr,"\rweird pinfo.buffer_size:%d\n",pinfo.buffer_size);
#endif

			alsa_pcm_flush_playback(pcm_h);

			/* set new parameters */
			if(alsa_pcm_playback_format(pcm_h,&pformat)<0)
#else
            if( alsa_pcm_set_params(pcm_h, pformat, 
                SND_PCM_ACCESS_RW_INTERLEAVED,
                channels,
                rate,
                1,
                500000 /* 0.5sec */
                ) < 0)
#endif
            {
				alsa_pcm_close(pcm_h);
				pcm_h=NULL;
#ifdef OLD_ALSA
				continue;
#else
                goto END;
#endif
			}

            global_frame_size = channels*(md_mode&DMODE_16BITS?2:1);
#ifdef OLD_ALSA
			/* compute a fragmentsize hint
			   each fragment should be shorter than, but close to, half a
			   second of playback */
			bps=(rate*global_frame_size)>>1;
			size=fragmentsize;while (size>bps) size>>=1;
#endif
#ifdef MIKMOD_DEBUG
			if (size < 16) {
				fprintf(stderr,"\rweird hint result:%d from %d, bps=%d\n",size,fragmentsize,bps);
				size=16;
			}
#endif
#ifdef OLD_ALSA
         buffer_size = size;
			memset(&pparams,0,sizeof(pparams));
			pparams.fragment_size=size;
			pparams.fragments_max=-1; /* choose the best */
			pparams.fragments_room=-1;
			if(alsa_pcm_playback_params(pcm_h,&pparams)<0)
            {
				alsa_pcm_close(pcm_h);
				pcm_h=NULL;
				continue;
			}
#else
            /* choose all parameters */
            err = alsa_pcm_hw_params_any(pcm_h, hwparams);
            if (err < 0) {
                printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
                goto END;
            }

            {
                snd_pcm_uframes_t temp_u_buffer_size, temp_u_period_size;
                err = alsa_pcm_get_params(pcm_h, &temp_u_buffer_size, &temp_u_period_size);
                if (err < 0) {
                    alsa_pcm_close(pcm_h);
                    pcm_h=NULL;
                    printf("Unable to get buffer size for playback: %s\n", alsa_strerror(err));
                    goto END;
                }
                buffer_size_in_frames = 1200;
                period_size = temp_u_period_size;
            }

            /* The set_swparams function was taken from test/pcm.c
             * in the alsa-lib distribution*/
            if ((err = set_swparams(pcm_h, swparams)) < 0) {
                printf("Setting of swparams failed: %s\n", snd_strerror(err));
                goto END;
            }
#endif

			if (!(audiobuffer=(SBYTE*)MikMod_malloc(
#ifdef OLD_ALSA
                        fragmentsize
#else
                        buffer_size_in_frames * global_frame_size
#endif
                        ))) {
#ifdef OLD_ALSA
				alsa_ctl_close(ctl_h);
#else
                alsa_pcm_close(pcm_h);
#endif
				return 1;
			}

			/* sound device is ready to work */
			if (VC_Init()) {
#ifdef OLD_ALSA
				alsa_ctl_close(ctl_h);
#else
                alsa_pcm_close(pcm_h);
#endif
				return 1;
			} else
			  return 0;
		}

#ifdef OLD_ALSA
		alsa_ctl_close(ctl_h);
#else
        alsa_pcm_close(pcm_h);
#endif
	}
END:
	return 1;
}
Exemple #10
0
static
int config(struct audio_config *config)
{
    int err;

    snd_pcm_hw_params_alloca(&alsa_hwparams);
    snd_pcm_sw_params_alloca(&alsa_swparams);

    bitdepth	= config->precision;
    channels	= config->channels;
    rate		= config->speed;

    if ( bitdepth == 0 )
        config->precision = bitdepth = 32;

    switch (bitdepth)
    {
    case 8:
        alsa_format = SND_PCM_FORMAT_U8;
        audio_pcm   = audio_pcm_u8;
        break;
    case 16:
        alsa_format = SND_PCM_FORMAT_S16;
#if __BYTE_ORDER == __LITTLE_ENDIAN
        audio_pcm = audio_pcm_s16le;
#else
        audio_pcm = audio_pcm_s16be;
#endif
        break;
    case 24:
        config->precision = bitdepth = 32;
    case 32:
        alsa_format = SND_PCM_FORMAT_S32;
#if __BYTE_ORDER == __LITTLE_ENDIAN
        audio_pcm = audio_pcm_s32le;
#else
        audio_pcm = audio_pcm_s32be;
#endif
        break;
    default:
        audio_error="bitdepth not one of [8,16,24,32]";
        return -1;
    }

    sample_size	= bitdepth * channels / 8;

    err = set_hwparams(alsa_handle, alsa_hwparams, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
    if (err < 0) {
        audio_error=snd_strerror(err);
        return -1;
    }

    err = set_swparams(alsa_handle, alsa_swparams);
    if (err < 0) {
        audio_error=snd_strerror(err);
        return -1;
    }

    err = snd_pcm_prepare(alsa_handle);
    if (err < 0) {
        audio_error=snd_strerror(err);
        return -1;
    }

    buf = malloc(buffer_size);
    if (buf == NULL) {
        audio_error="unable to allocate output buffer table";
        return -1;
    }

    return 0;

}
Exemple #11
0
static gboolean
gst_alsasrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
{
  GstAlsaSrc *alsa;
  gint err;

  alsa = GST_ALSA_SRC (asrc);

  if (!alsasrc_parse_spec (alsa, spec))
    goto spec_parse;

  CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block);

  CHECK (set_hwparams (alsa), hw_params_failed);
  CHECK (set_swparams (alsa), sw_params_failed);
  CHECK (snd_pcm_prepare (alsa->handle), prepare_failed);

  alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info);
  spec->segsize = alsa->period_size * alsa->bpf;
  spec->segtotal = alsa->buffer_size / alsa->period_size;

  {
    snd_output_t *out_buf = NULL;
    char *msg = NULL;

    snd_output_buffer_open (&out_buf);
    snd_pcm_dump_hw_setup (alsa->handle, out_buf);
    snd_output_buffer_string (out_buf, &msg);
    GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg);
    snd_output_close (out_buf);
    snd_output_buffer_open (&out_buf);
    snd_pcm_dump_sw_setup (alsa->handle, out_buf);
    snd_output_buffer_string (out_buf, &msg);
    GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg);
    snd_output_close (out_buf);
  }

#ifdef SND_CHMAP_API_VERSION
  alsa_detect_channels_mapping (GST_OBJECT (alsa), alsa->handle, spec,
      alsa->channels, GST_AUDIO_BASE_SRC (alsa)->ringbuffer);
#endif /* SND_CHMAP_API_VERSION */

  return TRUE;

  /* ERRORS */
spec_parse:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Error parsing spec"));
    return FALSE;
  }
non_block:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Could not set device to blocking: %s", snd_strerror (err)));
    return FALSE;
  }
hw_params_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Setting of hwparams failed: %s", snd_strerror (err)));
    return FALSE;
  }
sw_params_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Setting of swparams failed: %s", snd_strerror (err)));
    return FALSE;
  }
prepare_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Prepare failed: %s", snd_strerror (err)));
    return FALSE;
  }
}
static gboolean
gst_alsasink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
{
  GstAlsaSink *alsa;
  gint err;

  alsa = GST_ALSA_SINK (asink);

  if (alsa->iec958) {
    snd_pcm_close (alsa->handle);
    alsa->handle = gst_alsa_open_iec958_pcm (GST_OBJECT (alsa), alsa->device);
    if (G_UNLIKELY (!alsa->handle)) {
      goto no_iec958;
    }
  }

  if (!alsasink_parse_spec (alsa, spec))
    goto spec_parse;

  CHECK (set_hwparams (alsa), hw_params_failed);
  CHECK (set_swparams (alsa), sw_params_failed);

  alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info);
  spec->segsize = alsa->period_size * alsa->bpf;
  spec->segtotal = alsa->buffer_size / alsa->period_size;

  {
    snd_output_t *out_buf = NULL;
    char *msg = NULL;

    snd_output_buffer_open (&out_buf);
    snd_pcm_dump_hw_setup (alsa->handle, out_buf);
    snd_output_buffer_string (out_buf, &msg);
    GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg);
    snd_output_close (out_buf);
    snd_output_buffer_open (&out_buf);
    snd_pcm_dump_sw_setup (alsa->handle, out_buf);
    snd_output_buffer_string (out_buf, &msg);
    GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg);
    snd_output_close (out_buf);
  }

#ifdef SND_CHMAP_API_VERSION
  if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) {
    snd_pcm_chmap_t *chmap = snd_pcm_get_chmap (alsa->handle);
    if (chmap && chmap->channels == alsa->channels) {
      GstAudioChannelPosition pos[8];
      if (alsa_chmap_to_channel_positions (chmap, pos))
        gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK
            (alsa)->ringbuffer, pos);
    }
    free (chmap);
  }
#endif /* SND_CHMAP_API_VERSION */

  return TRUE;

  /* ERRORS */
no_iec958:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_WRITE, (NULL),
        ("Could not open IEC958 (SPDIF) device for playback"));
    return FALSE;
  }
spec_parse:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Error parsing spec"));
    return FALSE;
  }
hw_params_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Setting of hwparams failed: %s", snd_strerror (err)));
    return FALSE;
  }
sw_params_failed:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Setting of swparams failed: %s", snd_strerror (err)));
    return FALSE;
  }
}