예제 #1
0
/* return 0 on success */
int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
                    int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
                    int *choutdev, int rate)
{
    int err, inchans = 0, outchans = 0, subunitdir;
    char devname[512];
    snd_output_t* out;
    int frag_size = (sys_blocksize ? sys_blocksize : ALSA_DEFFRAGSIZE);
    int nfrags, i, iodev, dev2;
    int wantinchans, wantoutchans, device;

    nfrags = sys_schedadvance * (float)rate / (1e6 * frag_size);
    /* save our belief as to ALSA's buffer size for later */
    alsa_buf_samps = nfrags * frag_size;
    alsa_nindev = alsa_noutdev = 0;
    alsa_jittermax = ALSA_DEFJITTERMAX;

    if (sys_verbose)
        post("audio buffer set to %d", (int)(0.001 * sys_schedadvance));

    for (iodev = 0; iodev < naudioindev; iodev++)
    {
        alsa_numbertoname(audioindev[iodev], devname, 512);
        err = snd_pcm_open(&alsa_indev[alsa_nindev].a_handle, devname,
                           SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
        check_error(err, "snd_pcm_open (input)");
        if (err < 0)
            continue;
        alsa_indev[alsa_nindev].a_devno = audioindev[iodev];
        snd_pcm_nonblock(alsa_indev[alsa_nindev].a_handle, 1);
        if (sys_verbose)
            post("opened input device name %s", devname);
        alsa_nindev++;
    }
    for (iodev = 0; iodev < naudiooutdev; iodev++)
    {
        alsa_numbertoname(audiooutdev[iodev], devname, 512);
        err = snd_pcm_open(&alsa_outdev[alsa_noutdev].a_handle, devname,
                           SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
        check_error(err, "snd_pcm_open (output)");
        if (err < 0)
            continue;
        alsa_outdev[alsa_noutdev].a_devno = audiooutdev[iodev];
        snd_pcm_nonblock(alsa_outdev[alsa_noutdev].a_handle, 1);
        alsa_noutdev++;
    }
    if (!alsa_nindev && !alsa_noutdev)
        goto blewit;

    /* If all the open devices support mmap_noninterleaved, let's call
    Wini's code in s_audio_alsamm.c */
    alsa_usemmap = 1;
    for (iodev = 0; iodev < alsa_nindev; iodev++)
        if (!alsaio_canmmap(&alsa_indev[iodev]))
            alsa_usemmap = 0;
    for (iodev = 0; iodev < alsa_noutdev; iodev++)
        if (!alsaio_canmmap(&alsa_outdev[iodev]))
            alsa_usemmap = 0;
    if (alsa_usemmap)
    {
        post("using mmap audio interface");
        if (alsamm_open_audio(rate))
            goto blewit;
        else return (0);
    }
    for (iodev = 0; iodev < alsa_nindev; iodev++)
    {
        int channels = chindev[iodev];
        if (alsaio_setup(&alsa_indev[iodev], 0, &channels, &rate,
                         nfrags, frag_size) < 0)
            goto blewit;
        inchans += channels;
    }
    for (iodev = 0; iodev < alsa_noutdev; iodev++)
    {
        int channels = choutdev[iodev];
        if (alsaio_setup(&alsa_outdev[iodev], 1, &channels, &rate,
                         nfrags, frag_size) < 0)
            goto blewit;
        outchans += channels;
    }
    if (!inchans && !outchans)
        goto blewit;

    for (iodev = 0; iodev < alsa_nindev; iodev++)
        snd_pcm_prepare(alsa_indev[iodev].a_handle);
    for (iodev = 0; iodev < alsa_noutdev; iodev++)
        snd_pcm_prepare(alsa_outdev[iodev].a_handle);

    /* if duplex we can link the channels so they start together */
    for (iodev = 0; iodev < alsa_nindev; iodev++)
        for (dev2 = 0; dev2 < alsa_noutdev; dev2++)
        {
            if (alsa_indev[iodev].a_devno == alsa_outdev[iodev].a_devno)
            {
                snd_pcm_link(alsa_indev[iodev].a_handle,
                             alsa_outdev[iodev].a_handle);
            }
        }

    /* allocate the status variables */
    if (!alsa_status)
    {
        err = snd_pcm_status_malloc(&alsa_status);
        check_error(err, "snd_pcm_status_malloc");
    }

    /* fill the buffer with silence */
    memset(alsa_snd_buf, 0, alsa_snd_bufsize);

    if (outchans)
    {
        i = (frag_size * nfrags)/DEFDACBLKSIZE + 1;
        while (i--)
        {
            for (iodev = 0; iodev < alsa_noutdev; iodev++)
                snd_pcm_writei(alsa_outdev[iodev].a_handle, alsa_snd_buf,
                               DEFDACBLKSIZE);
        }
    }
    else if (inchans)
    {
        for (iodev = 0; iodev < alsa_nindev; iodev++)
            if ((err = snd_pcm_start(alsa_indev[iodev].a_handle)) < 0)
                check_error(err, "input start failed\n");
    }
    return (0);
blewit:
    sys_inchannels = 0;
    sys_outchannels = 0;
    alsa_close_audio();
    return (1);
}
예제 #2
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);
}
예제 #3
0
int alsa_init(alsa_dev_t *dev, void *ptr, void (*callback)(snd_async_handler_t *))
{
  snd_pcm_t *phandle;
  snd_pcm_t *chandle;
  
  int err;
  snd_pcm_hw_params_t *hwparams_capture, *hwparams_playback;
  snd_pcm_sw_params_t *swparams_capture, *swparams_playback;
    
  struct sched_param param;
  
  err = sched_getparam(0, &param);
  if (err < 0) {
    perror("sched_getparam():");
    exit(-1);
  }
  
  param.sched_priority = sched_get_priority_max(SCHED_FIFO);
  err = sched_setscheduler(0, SCHED_FIFO, &param);
  if (err < 0) {
    perror("sched_setscheduler():");
   exit(-1);
  }  

  snd_pcm_hw_params_alloca(&hwparams_capture);
  snd_pcm_sw_params_alloca(&swparams_capture);  
  
  snd_pcm_hw_params_alloca(&hwparams_playback);
  snd_pcm_sw_params_alloca(&swparams_playback);   
  
  err = snd_output_stdio_attach(&dev->output, stdout, 0);
  if (err < 0) {
    printf("Output failed: %s\n", snd_strerror(err));
    exit(-1);
  }  
  
  printf("Playback device is %s\n", dev->pdevice);
  printf("Stream parameters are %dHz, %s, %d channels\n", dev->rate, snd_pcm_format_name(dev->format), dev->channels);
  
  if ((err = snd_pcm_open(&phandle, dev->pdevice, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
    printf("Playback open error: %s\n", snd_strerror(err));
    exit(-1);
  }
  
  if ((err = alsa_set_hwparams(dev, phandle, hwparams_playback, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) {
    printf("Setting of hwparams_playback failed: %s\n", snd_strerror(err));
    exit(-1);
  }
  
  if ((err = alsa_set_swparams(dev, phandle, swparams_playback)) < 0) {
    printf("Setting of swparams_playback failed: %s\n", snd_strerror(err));
    exit(-1);
  }
  
  snd_pcm_dump(phandle, dev->output);  
  
  printf("Capture device is %s\n", dev->cdevice);
  
  if ((err = snd_pcm_open(&chandle, dev->cdevice, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
    printf("Capture open error: %s\n", snd_strerror(err));
    exit(-1);
  }
  
  if ((err = alsa_set_hwparams(dev, chandle, hwparams_capture, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) {
    printf("Setting of hwparams_capture failed: %s\n", snd_strerror(err));
    exit(-1);
  }
  
  if ((err = alsa_set_swparams(dev, chandle, swparams_capture)) < 0) {
    printf("Setting of swparams_capture failed: %s\n", snd_strerror(err));
    exit(-1);
  }
  
  snd_pcm_dump(chandle, dev->output);    
  
  if ((err = snd_pcm_link(phandle, chandle)) < 0)
  {
    printf("snd_pcm_link() failed: %s\n", snd_strerror(err));
    exit(-1);    
  }
  
  dev->chandle = chandle;
  dev->phandle = phandle;

  err = alsa_async_direct_loop(dev, ptr, callback);
  if (err < 0)
    printf("Transfer failed: %s\n", snd_strerror(err));  
  
  return 0;  
}
예제 #4
0
int main(int argc, char *argv[])
{
	struct option long_option[] =
	{
		{"help", 0, NULL, 'h'},
		{"pdevice", 1, NULL, 'P'},
		{"cdevice", 1, NULL, 'C'},
		{"min", 1, NULL, 'm'},
		{"max", 1, NULL, 'M'},
		{"frames", 1, NULL, 'F'},
		{"format", 1, NULL, 'f'},
		{"channels", 1, NULL, 'c'},
		{"rate", 1, NULL, 'r'},
		{"seconds", 1, NULL, 's'},
		{"block", 0, NULL, 'b'},
		{"time", 1, NULL, 't'},
		{"poll", 0, NULL, 'p'},
		{"effect", 0, NULL, 'e'},
		{NULL, 0, NULL, 0},
	};
	snd_pcm_t *phandle, *chandle;
	char *buffer;
	int err, latency, morehelp;
	int ok;
	snd_timestamp_t p_tstamp, c_tstamp;
	ssize_t r;
	size_t frames_in, frames_out, in_max;
	int effect = 0;
	morehelp = 0;
	while (1) {
		int c;
		if ((c = getopt_long(argc, argv, "hP:C:m:M:F:f:c:r:s:bt:pe", long_option, NULL)) < 0)
			break;
		switch (c) {
		case 'h':
			morehelp++;
			break;
		case 'P':
			pdevice = strdup(optarg);
			break;
		case 'C':
			cdevice = strdup(optarg);
			break;
		case 'm':
			err = atoi(optarg) / 2;
			latency_min = err >= 4 ? err : 4;
			if (latency_max < latency_min)
				latency_max = latency_min;
			break;
		case 'M':
			err = atoi(optarg) / 2;
			latency_max = latency_min > err ? latency_min : err;
			break;
		case 'f':
			format = snd_pcm_format_value(optarg);
			if (format == SND_PCM_FORMAT_UNKNOWN) {
				printf("Unknown format, setting to default S16_LE\n");
				format = SND_PCM_FORMAT_S16_LE;
			}
			break;
		case 'c':
			err = atoi(optarg);
			channels = err >= 1 && err < 1024 ? err : 1;
			break;
		case 'r':
			err = atoi(optarg);
			rate = err >= 4000 && err < 200000 ? err : 44100;
			break;
		case 's':
			err = atoi(optarg);
			loop_sec = err >= 1 && err <= 100000 ? err : 30;
			break;
		case 'b':
			block = 1;
			break;
		case 't':
			tick_time = atoi(optarg);
			tick_time = tick_time < 0 ? 0 : tick_time;
			break;
		case 'p':
			use_poll = 1;
			break;
		case 'e':
			effect = 1;
			break;
		}
	}

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

	loop_limit = loop_sec * rate;
	latency = latency_min - 4;
	buffer = malloc((latency_max * snd_pcm_format_width(format) / 8) * 2);

	setscheduler();

	printf("Playback device is %s\n", pdevice);
	printf("Capture device is %s\n", cdevice);
	printf("Parameters are %iHz, %s, %i channels, %s mode\n", rate, snd_pcm_format_name(format), channels, block ? "blocking" : "non-blocking");
	printf("Wanted tick time: %ius, poll mode: %s\n", tick_time, use_poll ? "yes" : "no");
	printf("Loop limit is %li frames, minimum latency = %i, maximum latency = %i\n", loop_limit, latency_min * 2, latency_max * 2);

	if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, block ? 0 : SND_PCM_NONBLOCK)) < 0) {
		printf("Playback open error: %s\n", snd_strerror(err));
		return 0;
	}
	if ((err = snd_pcm_open(&chandle, cdevice, SND_PCM_STREAM_CAPTURE, block ? 0 : SND_PCM_NONBLOCK)) < 0) {
		printf("Record open error: %s\n", snd_strerror(err));
		return 0;
	}

	/* initialize the filter sweep variables */
	if (effect) {
		fs = (float) rate;
		BW = FILTER_BANDWIDTH;

		lfo = 0;
		dlfo = 2.*M_PI*FILTERSWEEP_LFO_FREQ/fs;

		x[0] = (float*) malloc(channels*sizeof(float));		
		x[1] = (float*) malloc(channels*sizeof(float));		
		x[2] = (float*) malloc(channels*sizeof(float));		
		y[0] = (float*) malloc(channels*sizeof(float));		
		y[1] = (float*) malloc(channels*sizeof(float));		
		y[2] = (float*) malloc(channels*sizeof(float));		
	}
			  
	while (1) {
		frames_in = frames_out = 0;
		if (setparams(phandle, chandle, &latency) < 0)
			break;
		showlatency(latency);
		if (tick_time_ok)
			printf("Using tick time %ius\n", tick_time_ok);
		if ((err = snd_pcm_link(chandle, phandle)) < 0) {
			printf("Streams link error: %s\n", snd_strerror(err));
			exit(0);
		}
		if (snd_pcm_format_set_silence(format, buffer, latency*channels) < 0) {
			fprintf(stderr, "silence error\n");
			break;
		}
		if (writebuf(phandle, buffer, latency, &frames_out) < 0) {
			fprintf(stderr, "write error\n");
			break;
		}
		if (writebuf(phandle, buffer, latency, &frames_out) < 0) {
			fprintf(stderr, "write error\n");
			break;
		}

		if ((err = snd_pcm_start(chandle)) < 0) {
			printf("Go error: %s\n", snd_strerror(err));
			exit(0);
		}
		gettimestamp(phandle, &p_tstamp);
		gettimestamp(chandle, &c_tstamp);
#if 0
		printf("Playback:\n");
		showstat(phandle, frames_out);
		printf("Capture:\n");
		showstat(chandle, frames_in);
#endif

		ok = 1;
		in_max = 0;
		while (ok && frames_in < loop_limit) {
			if (use_poll) {
				/* use poll to wait for next event */
				snd_pcm_wait(chandle, 1000);
			}
			if ((r = readbuf(chandle, buffer, latency, &frames_in, &in_max)) < 0)
				ok = 0;
			else {
				if (effect)
					applyeffect(buffer,r);
			 	if (writebuf(phandle, buffer, r, &frames_out) < 0)
					ok = 0;
			}
		}
		if (ok)
			printf("Success\n");
		else
			printf("Failure\n");
		printf("Playback:\n");
		showstat(phandle, frames_out);
		printf("Capture:\n");
		showstat(chandle, frames_in);
		showinmax(in_max);
		if (p_tstamp.tv_sec == p_tstamp.tv_sec &&
		    p_tstamp.tv_usec == c_tstamp.tv_usec)
			printf("Hardware sync\n");
		snd_pcm_drop(chandle);
		snd_pcm_nonblock(phandle, 0);
		snd_pcm_drain(phandle);
		snd_pcm_nonblock(phandle, !block ? 1 : 0);
		if (ok) {
#if 1
			printf("Playback time = %li.%i, Record time = %li.%i, diff = %li\n",
			       p_tstamp.tv_sec,
			       (int)p_tstamp.tv_usec,
			       c_tstamp.tv_sec,
			       (int)c_tstamp.tv_usec,
			       timediff(p_tstamp, c_tstamp));
#endif
			break;
		}
		snd_pcm_unlink(chandle);
		snd_pcm_hw_free(phandle);
		snd_pcm_hw_free(chandle);
	}
	snd_pcm_close(phandle);
	snd_pcm_close(chandle);
	return 0;
}
예제 #5
0
AlsaDevice *alsa_device_open(char *device_name, unsigned int rate, int channels, int period)
{
   int dir;
   int err;
   snd_pcm_hw_params_t *hw_params;
   snd_pcm_sw_params_t *sw_params;
   snd_pcm_uframes_t period_size = period;
   snd_pcm_uframes_t buffer_size = PERIODS*period;
   static snd_output_t *jcd_out;
   AlsaDevice *dev = malloc(sizeof(*dev));
   if (!dev)
      return NULL;
   dev->device_name = malloc(1+strlen(device_name));
   if (!dev->device_name)
   {
      free(dev);
      return NULL;
   }
   strcpy(dev->device_name, device_name);
   dev->channels = channels;
   dev->period = period;
   err = snd_output_stdio_attach(&jcd_out, stdout, 0);
   
   if ((err = snd_pcm_open (&dev->capture_handle, dev->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
      fprintf (stderr, "cannot open audio device %s (%s)\n",
               dev->device_name,
               snd_strerror (err));
      assert(0);
   }

   if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
      fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
               snd_strerror (err));
      assert(0);
   }

   if ((err = snd_pcm_hw_params_any (dev->capture_handle, hw_params)) < 0) {
      fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
               snd_strerror (err));
      assert(0);
   }

   if ((err = snd_pcm_hw_params_set_access (dev->capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
      fprintf (stderr, "cannot set access type (%s)\n",
               snd_strerror (err));
      assert(0);
   }

   if ((err = snd_pcm_hw_params_set_format (dev->capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
      fprintf (stderr, "cannot set sample format (%s)\n",
               snd_strerror (err));
      assert(0);
   }

   if ((err = snd_pcm_hw_params_set_rate_near (dev->capture_handle, hw_params, &rate, 0)) < 0) {
      fprintf (stderr, "cannot set sample rate (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   /*fprintf (stderr, "rate = %d\n", rate);*/

   if ((err = snd_pcm_hw_params_set_channels (dev->capture_handle, hw_params, channels)) < 0) {
      fprintf (stderr, "cannot set channel count (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   
   period_size = period;
   dir = 0;
   if ((err = snd_pcm_hw_params_set_period_size_near (dev->capture_handle, hw_params, &period_size, &dir)) < 0) {
      fprintf (stderr, "cannot set period size (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   
   if ((err = snd_pcm_hw_params_set_periods (dev->capture_handle, hw_params, PERIODS, 0)) < 0) {
      fprintf (stderr, "cannot set number of periods (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   
   buffer_size = period_size * PERIODS;
   dir=0;
   if ((err = snd_pcm_hw_params_set_buffer_size_near (dev->capture_handle, hw_params, &buffer_size)) < 0) {
      fprintf (stderr, "cannot set buffer time (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   
   if ((err = snd_pcm_hw_params (dev->capture_handle, hw_params)) < 0) {
      fprintf (stderr, "cannot set capture parameters (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   /*snd_pcm_dump_setup(dev->capture_handle, jcd_out);*/
   snd_pcm_hw_params_free (hw_params);

   if ((err = snd_pcm_sw_params_malloc (&sw_params)) < 0) {
      fprintf (stderr, "cannot allocate software parameters structure (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   if ((err = snd_pcm_sw_params_current (dev->capture_handle, sw_params)) < 0) {
      fprintf (stderr, "cannot initialize software parameters structure (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   if ((err = snd_pcm_sw_params_set_avail_min (dev->capture_handle, sw_params, period)) < 0) {
      fprintf (stderr, "cannot set minimum available count (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   if ((err = snd_pcm_sw_params (dev->capture_handle, sw_params)) < 0) {
      fprintf (stderr, "cannot set software parameters (%s)\n",
               snd_strerror (err));
      assert(0);
   }   
   
   
   if ((err = snd_pcm_open (&dev->playback_handle, dev->device_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
      fprintf (stderr, "cannot open audio device %s (%s)\n",
               dev->device_name,
               snd_strerror (err));
      assert(0);
   }
   
   if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
      fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
               snd_strerror (err));
      assert(0);
   }

   if ((err = snd_pcm_hw_params_any (dev->playback_handle, hw_params)) < 0) {
      fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
               snd_strerror (err));
      assert(0);
   }

   if ((err = snd_pcm_hw_params_set_access (dev->playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
      fprintf (stderr, "cannot set access type (%s)\n",
               snd_strerror (err));
      assert(0);
   }

   if ((err = snd_pcm_hw_params_set_format (dev->playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
      fprintf (stderr, "cannot set sample format (%s)\n",
               snd_strerror (err));
      assert(0);
   }

   if ((err = snd_pcm_hw_params_set_rate_near (dev->playback_handle, hw_params, &rate, 0)) < 0) {
      fprintf (stderr, "cannot set sample rate (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   /*fprintf (stderr, "rate = %d\n", rate);*/

   if ((err = snd_pcm_hw_params_set_channels (dev->playback_handle, hw_params, channels)) < 0) {
      fprintf (stderr, "cannot set channel count (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   
   period_size = period;
   dir = 0;
   if ((err = snd_pcm_hw_params_set_period_size_near (dev->playback_handle, hw_params, &period_size, &dir)) < 0) {
      fprintf (stderr, "cannot set period size (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   if ((err = snd_pcm_hw_params_set_periods (dev->playback_handle, hw_params, PERIODS, 0)) < 0) {
      fprintf (stderr, "cannot set number of periods (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   buffer_size = period_size * PERIODS;
   dir=0;
   if ((err = snd_pcm_hw_params_set_buffer_size_near (dev->playback_handle, hw_params, &buffer_size)) < 0) {
      fprintf (stderr, "cannot set buffer time (%s)\n",
               snd_strerror (err));
      assert(0);
   }


   if ((err = snd_pcm_hw_params (dev->playback_handle, hw_params)) < 0) {
      fprintf (stderr, "cannot set playback parameters (%s)\n",
               snd_strerror (err));
      assert(0);
   }

   /*snd_pcm_dump_setup(dev->playback_handle, jcd_out);*/
   snd_pcm_hw_params_free (hw_params);

   
   if ((err = snd_pcm_sw_params_malloc (&sw_params)) < 0) {
      fprintf (stderr, "cannot allocate software parameters structure (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   if ((err = snd_pcm_sw_params_current (dev->playback_handle, sw_params)) < 0) {
      fprintf (stderr, "cannot initialize software parameters structure (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   if ((err = snd_pcm_sw_params_set_avail_min (dev->playback_handle, sw_params, period)) < 0) {
      fprintf (stderr, "cannot set minimum available count (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   if ((err = snd_pcm_sw_params_set_start_threshold (dev->playback_handle, sw_params, period)) < 0) {
      fprintf (stderr, "cannot set start mode (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   if ((err = snd_pcm_sw_params (dev->playback_handle, sw_params)) < 0) {
      fprintf (stderr, "cannot set software parameters (%s)\n",
               snd_strerror (err));
      assert(0);
   }
  
   
   snd_pcm_link(dev->capture_handle, dev->playback_handle);
   if ((err = snd_pcm_prepare (dev->capture_handle)) < 0) {
      fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   if ((err = snd_pcm_prepare (dev->playback_handle)) < 0) {
      fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   
   dev->readN = snd_pcm_poll_descriptors_count(dev->capture_handle);
   dev->writeN = snd_pcm_poll_descriptors_count(dev->playback_handle);

   dev->read_fd = malloc(dev->readN*sizeof(*dev->read_fd));
   /*printf ("descriptors: %d %d\n", dev->readN, dev->writeN);*/
   if (snd_pcm_poll_descriptors(dev->capture_handle, dev->read_fd, dev->readN) != dev->readN)
   {
      fprintf (stderr, "cannot obtain capture file descriptors (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   
   dev->write_fd = malloc(dev->writeN*sizeof(*dev->read_fd));
   if (snd_pcm_poll_descriptors(dev->playback_handle, dev->write_fd, dev->writeN) != dev->writeN)
   {
      fprintf (stderr, "cannot obtain playback file descriptors (%s)\n",
               snd_strerror (err));
      assert(0);
   }
   return dev;
}
예제 #6
0
/**
 * \brief Opens a ordinary pcm instance
 * \param ppcm Returned ordinary pcm handle
 * \param playback_name ASCII identifier of the ordinary pcm handle (playback)
 * \param capture_name ASCII identifier of the ordinary pcm handle (capture)
 * \param lconf Local configuration (might be NULL - use global configuration)
 * \return 0 on success otherwise a negative error code
 */
int sndo_pcm_open(sndo_pcm_t **ppcm,
		  const char *playback_name,
		  const char *capture_name,
		  struct alisp_cfg *lconf)
{
	int err = 0;
	sndo_pcm_t *pcm;
	
	assert(ppcm);
	assert(playback_name || capture_name);
	*ppcm = NULL;
	pcm = calloc(1, sizeof(sndo_pcm_t));
	if (pcm == NULL)
		return -ENOMEM;
	if (playback_name) {
		err = snd_pcm_hw_params_malloc(&pcm->p_hw_params);
		if (err < 0)
			goto __end;
		err = snd_pcm_sw_params_malloc(&pcm->p_sw_params);
	}
	if (capture_name) {
		err = snd_pcm_hw_params_malloc(&pcm->c_hw_params);
		if (err < 0)
			goto __end;
		err = snd_pcm_sw_params_malloc(&pcm->p_sw_params);
	}
	if (err < 0)
		goto __end;
	if (lconf) {
		if (playback_name) {
			err = snd_pcm_open_lconf(&pcm->playback, playback_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK, NULL);
			if (err < 0)
				goto __end;
		}
		if (capture_name) {
			err = snd_pcm_open_lconf(&pcm->capture, playback_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK, NULL);
			if (err < 0)
				goto __end;
		}
	} else {
		if (playback_name) {
			err = snd_pcm_open(&pcm->playback, playback_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
			if (err < 0)
				goto __end;
		}
		if (capture_name) {
			err = snd_pcm_open(&pcm->capture, playback_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
			if (err < 0)
				goto __end;
		}
	}
	if (pcm->playback && pcm->capture) {
		err = snd_pcm_link(pcm->playback, pcm->capture);
		if (err < 0)
			goto __end;
		pcm->master = pcm->playback;
	}
      __end:
	if (err < 0)
		sndo_pcm_close(pcm);
	return err;
}
예제 #7
0
파일: alsa.c 프로젝트: ipoerner/transsip
struct alsa_dev *alsa_open(char *devname, unsigned int rate,
			   int channels, int period)
{
	int ret;
	struct alsa_dev *dev;

	if (!devname)
		devname = "plughw:0,0";

	dev = xzmalloc(sizeof(*dev));
	dev->name = xstrdup(devname);
	dev->channels = channels;
	dev->period = period;

	ret = snd_pcm_open(&dev->capture_handle, dev->name,
			   SND_PCM_STREAM_CAPTURE, 0);
	if (ret < 0)
		syslog_panic("Cannot open audio capture device %s: %s\n",
			     dev->name, snd_strerror(ret));
	alsa_set_hw_params(dev, dev->capture_handle, rate, channels, period);
	alsa_set_sw_params(dev, dev->capture_handle, period, 0);

	ret = snd_pcm_open(&dev->playback_handle, dev->name,
			   SND_PCM_STREAM_PLAYBACK, 0);
	if (ret < 0)
		syslog_panic("Cannot open audio playback device %s: %s\n",
			     dev->name, snd_strerror(ret));
	alsa_set_hw_params(dev, dev->playback_handle, rate, channels, period);
	alsa_set_sw_params(dev, dev->playback_handle, period, 1);

	snd_pcm_link(dev->capture_handle, dev->playback_handle);

	ret = snd_pcm_prepare(dev->capture_handle);
	if (ret < 0)
		syslog_panic("Cannot prepare audio interface: %s\n",
			     snd_strerror(ret));

	ret = snd_pcm_prepare(dev->playback_handle);
	if (ret < 0)
		syslog_panic("Cannot prepare audio interface: %s\n",
			     snd_strerror(ret));

	dev->read_fds = snd_pcm_poll_descriptors_count(dev->capture_handle);
	dev->write_fds = snd_pcm_poll_descriptors_count(dev->playback_handle);

	dev->read_fd = xzmalloc(dev->read_fds * sizeof(*dev->read_fd));
	ret = snd_pcm_poll_descriptors(dev->capture_handle, dev->read_fd,
				       dev->read_fds);
	if (ret != dev->read_fds)
		syslog_panic("Cannot obtain capture file descriptors: %s\n",
			     snd_strerror(ret));

	dev->write_fd = xzmalloc(dev->write_fds * sizeof(*dev->write_fd));
	ret = snd_pcm_poll_descriptors(dev->playback_handle, dev->write_fd,
				       dev->write_fds);
	if (ret != dev->write_fds)
		syslog_panic("Cannot obtain playback file descriptors: %s\n",
			     snd_strerror(ret));

	return dev;
}