Example #1
0
static void alsa_fill_w (snd_pcm_t *pcm_handle)
{
	snd_pcm_hw_params_t *hwparams=NULL;
	int channels;
        snd_pcm_uframes_t buffer_size;
	int buffer_size_bytes;
	void *buffer;

	/* Allocate the snd_pcm_hw_params_t structure on the stack. */
	snd_pcm_hw_params_alloca(&hwparams);
	snd_pcm_hw_params_current(pcm_handle, hwparams);

	/* get channels */
	snd_pcm_hw_params_get_channels (hwparams, &channels);

	/* get buffer size */
	snd_pcm_hw_params_get_buffer_size (hwparams, &buffer_size);

	/* fill half */
	buffer_size /= 2;

	/* allocate buffer assuming 2 bytes per sample */
	buffer_size_bytes = buffer_size * channels * 2;
	buffer = alloca (buffer_size_bytes);
	memset (buffer, 0, buffer_size_bytes);

	/* write data */
	snd_pcm_writei(pcm_handle, buffer, buffer_size);
}
Example #2
0
    result alsa_init(Soloud *aSoloud, unsigned int aFlags, unsigned int aSamplerate, unsigned int aBuffer, unsigned int aChannels)
    {
        ALSAData *data = new ALSAData;
        memset(data, 0, sizeof(ALSAData));
        aSoloud->mBackendData = data;
        aSoloud->mBackendCleanupFunc = alsaCleanup;
        data->samples = aBuffer;
        data->channels = 2;
        data->soloud = aSoloud;

        int rc;
        snd_pcm_t *handle;
        rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
        if (rc < 0)
        {
            return UNKNOWN_ERROR;
        }
        
        data->alsaDeviceHandle = handle;
        
        snd_pcm_hw_params_t *params;
        snd_pcm_hw_params_alloca(&params);
        snd_pcm_hw_params_any(handle, params);

        snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
        snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
        snd_pcm_hw_params_set_channels(handle, params, 2);
        snd_pcm_hw_params_set_buffer_size(handle, params, aBuffer);
        
        unsigned int val = aSamplerate;
        int dir = 0;
        rc = snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
        if (rc < 0)
        {
            return UNKNOWN_ERROR;
        }

        rc = snd_pcm_hw_params(handle, params);
        if (rc < 0) 
        {
            return UNKNOWN_ERROR;
        }

        snd_pcm_hw_params_get_rate(params, &val, &dir);
        aSamplerate = val;
        snd_pcm_hw_params_get_channels(params, &val);
        data->channels = val;

        data->buffer = new float[data->samples*data->channels];
        data->sampleBuffer = new short[data->samples*data->channels];
        aSoloud->postinit(aSamplerate, data->samples * data->channels, aFlags, 2);
        data->threadHandle = Thread::createThread(alsaThread, data);
        if (0 == data->threadHandle)
        {
            return UNKNOWN_ERROR;
        }
        aSoloud->mBackendString = "ALSA";
        return 0;
    }
static int ste_iop_hwparams(snd_pcm_ioplug_t *io,
    snd_pcm_hw_params_t *params)
{
    int err = 0;
    int direction;
    ste_iop_t *ste_iop = io->private_data;

    /* Get and print HW params */

    /* PCM format */
    err = snd_pcm_hw_params_get_format(params, &ste_iop->hwparams.pcm_format);

    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM format: %s\n", snd_strerror(err));
        return err;
    }

    /* PCM access mode */
    err = snd_pcm_hw_params_get_access(params, &ste_iop->hwparams.pcm_access);

    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM Access mode: %s\n",
            snd_strerror(err));
        return err;
    }

    /* PCM number of channels */
    err = snd_pcm_hw_params_get_channels(params, &ste_iop->hwparams.pcm_channels);

    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM number of channels: %s\n",
            snd_strerror(err));
        return err;
    }

    /* Sample Rate */
    err = snd_pcm_hw_params_get_rate(params, &ste_iop->hwparams.pcm_rate,
        &direction);
    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM Sample Rate: %s\n",
            snd_strerror(err));
        return err;
    }

    ste_iop->bufsz = ste_iop->hwparams.pcm_rate * 32 / 1000 * 2 * ste_iop->hwparams.pcm_channels;

    /* Period time */
    err = snd_pcm_hw_params_get_period_time(params, &ste_iop->hwparams.pcm_period_time,
        &direction);

    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to get HW param PCM period time: %s\n",
            snd_strerror(err));
        return err;
    }

    return 0;
}
Example #4
0
AudioSourceNix::AudioSourceNix(int c, int r)
    : AudioSource(c, r)
{
    int err;
    unsigned int ap_rate = rate;
    unsigned int ap_chan = channels;

    err = snd_pcm_open(&device, ADDR, SND_PCM_STREAM_CAPTURE, 0);
    if (err < 0) { g2g = PR_FALSE; return; }

    err = snd_pcm_hw_params_malloc(&params);
    if (err < 0) { g2g = PR_FALSE; return; }

    err = snd_pcm_hw_params_any(device, params);
    if (err < 0) { g2g = PR_FALSE; return; }
    
    err = snd_pcm_hw_params_set_access(
        device, params, SND_PCM_ACCESS_RW_INTERLEAVED
    );
    if (err < 0) { g2g = PR_FALSE; return; }

    err = snd_pcm_hw_params_set_format(
        device, params, SND_PCM_FORMAT_S16_LE
    );
    if (err < 0) { g2g = PR_FALSE; return; }

    /* For rate and channels if we don't get
     * what we want, that's too bad */
    err = snd_pcm_hw_params_set_rate_near(
        device, params, &ap_rate, 0
    );
    if (err < 0) {
        err = snd_pcm_hw_params_get_rate(
            params, &ap_rate, 0
        );
        if (err < 0) { g2g = PR_FALSE; return; }
    }

    err = snd_pcm_hw_params_set_channels(
        device, params, ap_chan
    );
    if (err < 0) {
        err = snd_pcm_hw_params_get_channels(
            params, &ap_chan
        );
        if (err < 0) { g2g = PR_FALSE; return; }
    }

    g2g = PR_TRUE;
    rec = PR_FALSE;
    rate = ap_rate;
    channels = ap_chan;
    snd_pcm_close(device);
}
Example #5
0
int
snd_send(FILE * fp, size_t n)
{
    snd_pcm_format_t format;
    unsigned int    nchannels;
    snd_pcm_uframes_t period;
    snd_pcm_hw_params_t *params;
    snd_pcm_hw_params_alloca(&params);
    snd_pcm_hw_params_current(pcm, params);
    snd_pcm_hw_params_get_format(params, &format);
    snd_pcm_hw_params_get_channels(params, &nchannels);
    snd_pcm_hw_params_get_period_size(params, &period, 0);
    int             framesize =
        snd_pcm_format_width(format) / 8 * nchannels;
    unsigned char   buf[period * framesize * 128];
    size_t          l;
    while (n > sizeof(buf)) {
        if ((l = fread(buf, 1, sizeof(buf), fp))) {
            switch (snd_pcm_writei(pcm, buf, l / framesize)) {
            case -EBADF:
                return -1;
            case -EPIPE:
#ifndef NDEBUG
                snd_pcm_recover(pcm, -EPIPE, 0);
#else
                snd_pcm_prepare(pcm);
#endif
            }
        } else
            goto EOS;
        n -= l;
    }
    if ((l = fread(buf, 1, n, fp)))
        snd_pcm_writei(pcm, buf, l / framesize);
    if (l < n)
      EOS:if (ftell(fp) > 0)
            eputs("Unexpected end of stream");
    return snd_pcm_drain(pcm);
}
Example #6
0
    void alsa_print_info(snd_pcm_t * handle, snd_pcm_hw_params_t * hwp) {
        printf("device [%s] opened with\n",
               snd_pcm_name(handle));
        printf("\tstate=%s\n",
               snd_pcm_state_name(snd_pcm_state(handle)));
        unsigned int val, val2;
        snd_pcm_hw_params_get_access(hwp,
                                     (snd_pcm_access_t *) &val);
        printf("\taccess_type=%s\n",
               snd_pcm_access_name((snd_pcm_access_t)val));

        snd_pcm_hw_params_get_format(hwp, (snd_pcm_format_t *) &val);
        printf("\tformat=%s\n",
               snd_pcm_format_name((snd_pcm_format_t) val)
               );

        snd_pcm_hw_params_get_channels(hwp, &val);
        printf("\tchannels=%d\n", val);

        snd_pcm_hw_params_get_rate(hwp, &val, (int *) &val2);
        printf("\trate=%d fps\n", val);

        snd_pcm_hw_params_get_period_time(hwp,
                                          &val, (int *) &val2);
        printf("\tperiod_time=%d us\n", val);

        snd_pcm_uframes_t frames;
        snd_pcm_hw_params_get_period_size(hwp,
                                          &frames, (int *) &val2);
        printf("\tperiod_size=%d frames\n", (int)frames);

        snd_pcm_hw_params_get_buffer_size(hwp,
                                          (snd_pcm_uframes_t *) &val);
        printf("\tbuffer_size=%d frames\n", val);

        snd_pcm_hw_params_get_periods(hwp, &val, (int *) &val2);
        printf("\tperiods_per_buffer=%d periods\n", val);
    }
Example #7
0
int main()
{
    int rc;
    snd_pcm_t* handle;
    snd_pcm_hw_params_t* params;
    unsigned int val;
    unsigned int val2;
    int dir;
    snd_pcm_uframes_t frames;

    if ( (rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0)
    {
        std::cerr << "unable to open pcm devices: " << snd_strerror(rc) << std::endl;
        exit(1);
    }

    snd_pcm_hw_params_alloca(&params);

    snd_pcm_hw_params_any(handle, params);

    snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);

    snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);

    snd_pcm_hw_params_set_channels(handle, params, 2);

    val = 44100;

    snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);

    if ( (rc = snd_pcm_hw_params(handle, params)) < 0)
    {
        std::cerr << "unable to set hw parameters: " << snd_strerror(rc) << std::endl;
        exit(1);
    }

    std::cout << "PCM handle name = " << snd_pcm_name(handle) << std::endl;

    std::cout << "PCM state = " << snd_pcm_state_name(snd_pcm_state(handle)) << std::endl;

    snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *)&val);

    std::cout << "access type = " << snd_pcm_access_name((snd_pcm_access_t)val) << std::endl;

    snd_pcm_hw_params_get_format(params, (snd_pcm_format_t*)(&val));

    std::cout << "format = '" << snd_pcm_format_name((snd_pcm_format_t)val) << "' (" << snd_pcm_format_description((snd_pcm_format_t)val) << ")" << std::endl;

    snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val);
    std::cout << "subformat = '" <<
              snd_pcm_subformat_name((snd_pcm_subformat_t)val) << "' (" << snd_pcm_subformat_description((snd_pcm_subformat_t)val) << ")" << std::endl;

    snd_pcm_hw_params_get_channels(params, &val);
    std::cout << "channels = " << val << std::endl;

    snd_pcm_hw_params_get_rate(params, &val, &dir);
    std::cout << "rate = " << val << " bps" << std::endl;

    snd_pcm_hw_params_get_period_time(params, &val, &dir);
    std::cout << "period time = " << val << " us" << std::endl;

    snd_pcm_hw_params_get_period_size(params, &frames, &dir);
    std::cout << "period size = " << static_cast<int>(frames) << " frames" << std::endl;

    snd_pcm_hw_params_get_buffer_time(params, &val, &dir);
    std::cout << "buffer time = " << val << " us" << std::endl;

    snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val);
    std::cout << "buffer size = " << val << " frames" << std::endl;

    snd_pcm_hw_params_get_periods(params, &val, &dir);
    std::cout << "periods per buffer = " << val << " frames" << std::endl;

    snd_pcm_hw_params_get_rate_numden(params, &val, &val2);
    std::cout << "exact rate = " << val/val2 << " bps" << std::endl;

    val = snd_pcm_hw_params_get_sbits(params);
    std::cout << "significant bits = " << val << std::endl;

    snd_pcm_hw_params_get_tick_time(params, &val, &dir);
    std::cout << "tick time = " << val << " us" << std::endl;

    val = snd_pcm_hw_params_is_batch(params);
    std::cout << "is batch = " << val << std::endl;

    val = snd_pcm_hw_params_is_block_transfer(params);
    std::cout << "is block transfer = " << val << std::endl;

    val = snd_pcm_hw_params_is_double(params);
    std::cout << "is double = " << val << std::endl;

    val = snd_pcm_hw_params_is_half_duplex(params);
    std::cout << "is half duplex = " << val << std::endl;

    val = snd_pcm_hw_params_is_joint_duplex(params);
    std::cout << "is joint duplex = " << val << std::endl;

    val = snd_pcm_hw_params_can_overrange(params);
    std::cout << "can overrange = " << val << std::endl;

    val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
    std::cout << "can mmap = " << val << std::endl;

    val = snd_pcm_hw_params_can_pause(params);
    std::cout << "can pause = " << val << std::endl;

    val = snd_pcm_hw_params_can_resume(params);
    std::cout << "can resume = " << val << std::endl;

    val = snd_pcm_hw_params_can_sync_start(params);
    std::cout << "can sync start = " << val << std::endl;

    snd_pcm_close(handle);

    return 0;
}
Example #8
0
int main() {
  int rc;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  unsigned int val, val2;
  int dir;
  snd_pcm_uframes_t frames;
  
  /* Open PCM device for playback. */
  rc = snd_pcm_open(&handle, "default",
                    SND_PCM_STREAM_PLAYBACK, 0);
  if (rc < 0) {
    fprintf(stderr, 
            "unable to open pcm device: %s\n",
            snd_strerror(rc));
    exit(1);
  }
  
  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_alloca(&params);

  /* Fill it in with default values. */
  snd_pcm_hw_params_any(handle, params);

  /* Set the desired hardware parameters. */

  /* Interleaved mode */
  snd_pcm_hw_params_set_access(handle, params,
                      SND_PCM_ACCESS_RW_INTERLEAVED);

  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(handle, params, 
                              SND_PCM_FORMAT_S16_LE);

  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(handle, params, 2);

  /* 44100 bits/second sampling rate (CD quality) */
  val = 44100;
  snd_pcm_hw_params_set_rate_near(handle, 
                                 params, &val, &dir);

  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(handle, params);
  if (rc < 0) {
    fprintf(stderr, 
            "unable to set hw parameters: %s\n",
            snd_strerror(rc));
    exit(1);
  }

  /* Display information about the PCM interface */

  printf("PCM handle name = '%s'\n",
         snd_pcm_name(handle));

  printf("PCM state = %s\n",
         snd_pcm_state_name(snd_pcm_state(handle)));

  snd_pcm_hw_params_get_access(params, 
                          (snd_pcm_access_t *) &val);
  printf("access type = %s\n", 
         snd_pcm_access_name((snd_pcm_access_t)val));

  snd_pcm_hw_params_get_format(params, &val);
  printf("format = '%s' (%s)\n",
    snd_pcm_format_name((snd_pcm_format_t)val),
    snd_pcm_format_description(
                             (snd_pcm_format_t)val));

  snd_pcm_hw_params_get_subformat(params,
                        (snd_pcm_subformat_t *)&val);
  printf("subformat = '%s' (%s)\n",
    snd_pcm_subformat_name((snd_pcm_subformat_t)val),
    snd_pcm_subformat_description(
                          (snd_pcm_subformat_t)val));

  snd_pcm_hw_params_get_channels(params, &val);
  printf("channels = %d\n", val);

  snd_pcm_hw_params_get_rate(params, &val, &dir);
  printf("rate = %d bps\n", val);

  snd_pcm_hw_params_get_period_time(params, 
                                    &val, &dir);
  printf("period time = %d us\n", val);

  snd_pcm_hw_params_get_period_size(params, 
                                    &frames, &dir);
  printf("period size = %d frames\n", (int)frames);

  snd_pcm_hw_params_get_buffer_time(params, 
                                    &val, &dir);
  printf("buffer time = %d us\n", val);

  snd_pcm_hw_params_get_buffer_size(params,
                         (snd_pcm_uframes_t *) &val);
  printf("buffer size = %d frames\n", val);

  snd_pcm_hw_params_get_periods(params, &val, &dir);
  printf("periods per buffer = %d frames\n", val);

  snd_pcm_hw_params_get_rate_numden(params,
                                    &val, &val2);
  printf("exact rate = %d/%d bps\n", val, val2);

  val = snd_pcm_hw_params_get_sbits(params);
  printf("significant bits = %d\n", val);

  snd_pcm_hw_params_get_tick_time(params, 
                                  &val, &dir);
  printf("tick time = %d us\n", val);

  val = snd_pcm_hw_params_is_batch(params);
  printf("is batch = %d\n", val);

  val = snd_pcm_hw_params_is_block_transfer(params);
  printf("is block transfer = %d\n", val);

  val = snd_pcm_hw_params_is_double(params);
  printf("is double = %d\n", val);

  val = snd_pcm_hw_params_is_half_duplex(params);
  printf("is half duplex = %d\n", val);

  val = snd_pcm_hw_params_is_joint_duplex(params);
  printf("is joint duplex = %d\n", val);

  val = snd_pcm_hw_params_can_overrange(params);
  printf("can overrange = %d\n", val);

  val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
  printf("can mmap = %d\n", val);

  val = snd_pcm_hw_params_can_pause(params);
  printf("can pause = %d\n", val);

  val = snd_pcm_hw_params_can_resume(params);
  printf("can resume = %d\n", val);

  val = snd_pcm_hw_params_can_sync_start(params);
  printf("can sync start = %d\n", val);

  snd_pcm_close(handle);

  return 0;
}
int main(int argc, char **argv){
   int i;
   int aver,val,val2;
   int16_t buf[BUFSIZE];
   double d_buffer[BUFSIZE];
   double pitch = 0.0;
   struct timespec before,after;
   struct pitch_tracker_params *settings;
   snd_pcm_uframes_t period_size = PERIOD_SIZE;

   //ALSA PCM configuration
   snd_pcm_t *handle;
   snd_pcm_hw_params_t *params;
   int dir,rc;
   snd_pcm_uframes_t frames;

   /* Open PCM device for capture */
   rc = snd_pcm_open( &handle, "default" , SND_PCM_STREAM_CAPTURE , 0);

   if(rc < 0 ){
      fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(rc));
      exit(1);
   }

   /* Allocate a hardware parameters object. */
   snd_pcm_hw_params_alloca(&params);

   /* Fill it in with default values. */
   snd_pcm_hw_params_any(handle, params);

   /* Set the desired hardware parameters. */

   /* Interleaved mode */
   snd_pcm_hw_params_set_access(handle, params,SND_PCM_ACCESS_RW_INTERLEAVED);

   /* unsigned 16-bit format */
   snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_S16);

   snd_pcm_hw_params_set_channels(handle, params, 1);

   /* 44100 bits/second sampling rate */
   val = 44100;
   snd_pcm_hw_params_set_rate_near(handle,params, &val, &dir);

   /* set size time*/
   snd_pcm_hw_params_set_period_size_near(handle, params, &period_size , &dir);

   /* write configuration */
   rc = snd_pcm_hw_params(handle,params);


   /*Display info*/

   printf("PCM handle name = '%s'\n",
         snd_pcm_name(handle));

   printf("PCM state = %s\n",
         snd_pcm_state_name(snd_pcm_state(handle)));

   snd_pcm_hw_params_get_access(params,
         (snd_pcm_access_t *) &val);
   printf("access type = %s\n",
         snd_pcm_access_name((snd_pcm_access_t)val));

   snd_pcm_hw_params_get_format(params, &val);
   printf("format = '%s' (%s)\n",
         snd_pcm_format_name((snd_pcm_format_t)val),
         snd_pcm_format_description(
            (snd_pcm_format_t)val));

   snd_pcm_hw_params_get_subformat(params,
         (snd_pcm_subformat_t *)&val);
   printf("subformat = '%s' (%s)\n",
         snd_pcm_subformat_name((snd_pcm_subformat_t)val),
         snd_pcm_subformat_description(
            (snd_pcm_subformat_t)val));

   snd_pcm_hw_params_get_channels(params, &val);
   printf("channels = %d\n", val);

   snd_pcm_hw_params_get_rate(params, &val, &dir);
   printf("rate = %d bps\n", val);

   snd_pcm_hw_params_get_period_time(params,
         &val, &dir);
   printf("period time = %d us\n", val);

   snd_pcm_hw_params_get_period_size(params,
         &frames, &dir);
   printf("period size = %d frames\n", (int)frames);

   snd_pcm_hw_params_get_buffer_time(params,
         &val, &dir);
   printf("buffer time = %d us\n", val);

   snd_pcm_hw_params_get_buffer_size(params,
         (snd_pcm_uframes_t *) &val);
   printf("buffer size = %d frames\n", val);

   snd_pcm_hw_params_get_periods(params, &val, &dir);
   printf("periods per buffer = %d frames\n", val);

   snd_pcm_hw_params_get_rate_numden(params,
         &val, &val2);
   printf("exact rate = %d/%d bps\n", val, val2);

   val = snd_pcm_hw_params_get_sbits(params);
   printf("significant bits = %d\n", val);

   val = snd_pcm_hw_params_is_batch(params);
   printf("is batch = %d\n", val);

   val = snd_pcm_hw_params_is_block_transfer(params);
   printf("is block transfer = %d\n", val);

   val = snd_pcm_hw_params_is_double(params);
   printf("is double = %d\n", val);

   val = snd_pcm_hw_params_is_half_duplex(params);
   printf("is half duplex = %d\n", val);

   val = snd_pcm_hw_params_is_joint_duplex(params);
   printf("is joint duplex = %d\n", val);

   val = snd_pcm_hw_params_can_overrange(params);
   printf("can overrange = %d\n", val);

   val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
   printf("can mmap = %d\n", val);

   val = snd_pcm_hw_params_can_pause(params);
   printf("can pause = %d\n", val);

   val = snd_pcm_hw_params_can_resume(params);
   printf("can resume = %d\n", val);

   val = snd_pcm_hw_params_can_sync_start(params);
   printf("can sync start = %d\n", val);

   settings = open_pitch_tracker();

   while(1){
      rc = snd_pcm_readi(handle, buf, frames);
      if (rc == -EPIPE) {
         /* EPIPE means overrun */
         fprintf(stderr, "overrun occurred\n");
         snd_pcm_prepare(handle);
      } else if (rc < 0) {
         fprintf(stderr,
               "error from read: %s\n",
               snd_strerror(rc));
      } else if (rc != (int)frames) {
         fprintf(stderr, "short read, read %d frames\n", rc);
      }


      for( i = 0 ; i< BUFSIZE ; i++){
         d_buffer[i] = (double) buf[i];
      }
      pitch = compute_pitch(d_buffer, BUFSIZE, S16, settings ,ACCURACY);
      if( pitch != 0.0 )
         printf("frequency -> %f\n",pitch);

      memset(buf,0,BUFSIZE);
   }


   close_pitch_tracker(&settings);
   snd_pcm_drain(handle);
   snd_pcm_close(handle);

   return 0;
}
Example #10
0
int alsa_hook_hw_params(alsa_hook_t alsa_hook, snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
	struct alsa_hook_stream_s *stream;

	snd_pcm_format_t format;
	snd_pcm_uframes_t period_size;
	snd_pcm_access_t access;
	int dir, ret;

	alsa_hook_get_stream(alsa_hook, pcm, &stream);
	if (unlikely((ret = alsa_hook_lock_write(alsa_hook, stream))))
		return ret;

	glc_log(alsa_hook->glc, GLC_DEBUG, "alsa_hook",
		 "%p: creating/updating configuration for stream %d",
		 stream->pcm, stream->id);

	/* extract information */
	if (unlikely((ret = snd_pcm_hw_params_get_format(params, &format)) < 0))
		goto err;
	stream->flags = 0; /* zero flags */
	stream->format = pcm_fmt_to_glc_fmt(format);
	if (unlikely(!stream->format)) {
		glc_log(alsa_hook->glc, GLC_ERROR, "alsa_hook",
			"%p: unsupported audio format 0x%02x", stream->pcm, format);
		ret = ENOTSUP;
		goto err;
	}
	if (unlikely((ret = snd_pcm_hw_params_get_rate(params, &stream->rate, &dir)) < 0))
		goto err;
	if (unlikely((ret = snd_pcm_hw_params_get_channels(params, &stream->channels)) < 0))
		goto err;
	if (unlikely((ret = snd_pcm_hw_params_get_period_size(params, &period_size, NULL)) < 0))
		goto err;
	if (unlikely((ret = snd_pcm_hw_params_get_access(params, &access)) < 0))
		goto err;
	if ((access == SND_PCM_ACCESS_RW_INTERLEAVED) ||
	    (access == SND_PCM_ACCESS_MMAP_INTERLEAVED))
		stream->flags |= GLC_AUDIO_INTERLEAVED;
	else if (access == SND_PCM_ACCESS_MMAP_COMPLEX) {
		stream->flags |= GLC_AUDIO_INTERLEAVED; /* convert to interleaved */
		stream->complex = 1; /* do conversion */
	} else {
		glc_log(alsa_hook->glc, GLC_ERROR, "alsa_hook",
			 "%p: unsupported access mode 0x%02x", stream->pcm, access);
		ret = ENOTSUP;
		goto err;
	}

	glc_log(alsa_hook->glc, GLC_DEBUG, "alsa_hook",
		 "%p: %d channels, rate %d, flags 0x%02x",
		 stream->pcm, stream->channels, stream->rate, stream->flags);

	stream->fmt = 1;
	if (alsa_hook->started) {
		if (unlikely((ret = alsa_hook_stream_init(alsa_hook, stream))))
			goto err;
	}

	alsa_hook_unlock_write(alsa_hook, stream);
	return 0;

err:
	glc_log(alsa_hook->glc, GLC_ERROR, "alsa_hook",
		 "%p: can't extract hardware configuration: %s (%d)",
		 stream->pcm, snd_strerror(ret), ret);

	alsa_hook_unlock_write(alsa_hook, stream);
	return ret;
}
Example #11
0
static int
palsa_set_hw_params (ddb_waveformat_t *fmt) {
    snd_pcm_hw_params_t *hw_params = NULL;
    int err = 0;

    memcpy (&plugin.fmt, fmt, sizeof (ddb_waveformat_t));
    if (!plugin.fmt.channels) {
        // generic format
        plugin.fmt.bps = 16;
        plugin.fmt.is_float = 0;
        plugin.fmt.channels = 2;
        plugin.fmt.samplerate = 44100;
        plugin.fmt.channelmask = 3;
    }

    snd_pcm_nonblock(audio, 0);
    snd_pcm_drain (audio);
    snd_pcm_nonblock(audio, 1);

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

    if ((err = snd_pcm_hw_params_any (audio, hw_params)) < 0) {
        fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
                snd_strerror (err));
        goto error;
    }

    if ((err = snd_pcm_hw_params_set_access (audio, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
        fprintf (stderr, "cannot set access type (%s)\n",
                snd_strerror (err));
        goto error;
    }

    snd_pcm_format_t sample_fmt;
    switch (plugin.fmt.bps) {
    case 8:
        sample_fmt = SND_PCM_FORMAT_S8;
        break;
    case 16:
#if WORDS_BIGENDIAN
        sample_fmt = SND_PCM_FORMAT_S16_BE;
#else
        sample_fmt = SND_PCM_FORMAT_S16_LE;
#endif
        break;
    case 24:
#if WORDS_BIGENDIAN
        sample_fmt = SND_PCM_FORMAT_S24_3BE;
#else
        sample_fmt = SND_PCM_FORMAT_S24_3LE;
#endif
        break;
    case 32:
        if (plugin.fmt.is_float) {
#if WORDS_BIGENDIAN
            sample_fmt = SND_PCM_FORMAT_FLOAT_BE;
#else
            sample_fmt = SND_PCM_FORMAT_FLOAT_LE;
#endif
        }
        else {
#if WORDS_BIGENDIAN
            sample_fmt = SND_PCM_FORMAT_S32_BE;
#else
            sample_fmt = SND_PCM_FORMAT_S32_LE;
#endif
        }
        break;
    }

    if ((err = snd_pcm_hw_params_set_format (audio, hw_params, sample_fmt)) < 0) {
        fprintf (stderr, "cannot set sample format to %d bps (error: %s), trying all supported formats\n", plugin.fmt.bps, snd_strerror (err));

        int fmt_cnt[] = { 16, 24, 32, 32, 8 };
#if WORDS_BIGENDIAN
        int fmt[] = { SND_PCM_FORMAT_S16_BE, SND_PCM_FORMAT_S24_3BE, SND_PCM_FORMAT_S32_BE, SND_PCM_FORMAT_FLOAT_BE, SND_PCM_FORMAT_S8, -1 };
#else
        int fmt[] = { SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_FLOAT_LE, SND_PCM_FORMAT_S8, -1 };
#endif

        // 1st try formats with higher bps
        int i = 0;
        for (i = 0; fmt[i] != -1; i++) {
            if (fmt[i] != sample_fmt && fmt_cnt[i] > plugin.fmt.bps) {
                if (snd_pcm_hw_params_set_format (audio, hw_params, fmt[i]) >= 0) {
                    fprintf (stderr, "Found compatible format %d bps\n", fmt_cnt[i]);
                    sample_fmt = fmt[i];
                    break;
                }
            }
        }
        if (fmt[i] == -1) {
            // next try formats with lower bps
            i = 0;
            for (i = 0; fmt[i] != -1; i++) {
                if (fmt[i] != sample_fmt && fmt_cnt[i] < plugin.fmt.bps) {
                    if (snd_pcm_hw_params_set_format (audio, hw_params, fmt[i]) >= 0) {
                        fprintf (stderr, "Found compatible format %d bps\n", fmt_cnt[i]);
                        sample_fmt = fmt[i];
                        break;
                    }
                }
            }
        }

        if (fmt[i] == -1) {
            fprintf (stderr, "Fallback format could not be found\n");
            goto error;
        }
    }

    snd_pcm_hw_params_get_format (hw_params, &sample_fmt);
    trace ("chosen sample format: %04Xh\n", (int)sample_fmt);

    int val = plugin.fmt.samplerate;
    int ret = 0;

    if ((err = snd_pcm_hw_params_set_rate_resample (audio, hw_params, conf_alsa_resample)) < 0) {
        fprintf (stderr, "cannot setup resampling (%s)\n",
                snd_strerror (err));
        goto error;
    }

    if ((err = snd_pcm_hw_params_set_rate_near (audio, hw_params, &val, &ret)) < 0) {
        fprintf (stderr, "cannot set sample rate (%s)\n",
                snd_strerror (err));
        goto error;
    }
    plugin.fmt.samplerate = val;
    trace ("chosen samplerate: %d Hz\n", val);

    int chanmin, chanmax;
    snd_pcm_hw_params_get_channels_min (hw_params, &chanmin);
    snd_pcm_hw_params_get_channels_max (hw_params, &chanmax);

    trace ("minchan: %d, maxchan: %d\n", chanmin, chanmax);
    int nchan = plugin.fmt.channels;
    if (nchan > chanmax) {
        nchan = chanmax;
    }
    else if (nchan < chanmin) {
        nchan = chanmin;
    }
    trace ("setting chan=%d\n", nchan);
    if ((err = snd_pcm_hw_params_set_channels (audio, hw_params, nchan)) < 0) {
        fprintf (stderr, "cannot set channel count (%s)\n",
                snd_strerror (err));
    }

    snd_pcm_hw_params_get_channels (hw_params, &nchan);
    trace ("alsa channels: %d\n", nchan);

    req_buffer_size = deadbeef->conf_get_int ("alsa.buffer", DEFAULT_BUFFER_SIZE);
    req_period_size = deadbeef->conf_get_int ("alsa.period", DEFAULT_PERIOD_SIZE);
    buffer_size = req_buffer_size;
    period_size = req_period_size;
    trace ("trying buffer size: %d frames\n", (int)buffer_size);
    trace ("trying period size: %d frames\n", (int)period_size);
    snd_pcm_hw_params_set_buffer_size_near (audio, hw_params, &buffer_size);
    snd_pcm_hw_params_set_period_size_near (audio, hw_params, &period_size, NULL);
    trace ("alsa buffer size: %d frames\n", (int)buffer_size);
    trace ("alsa period size: %d frames\n", (int)period_size);

    if ((err = snd_pcm_hw_params (audio, hw_params)) < 0) {
        fprintf (stderr, "cannot set parameters (%s)\n",
                snd_strerror (err));
        goto error;
    }

    plugin.fmt.is_float = 0;
    switch (sample_fmt) {
    case SND_PCM_FORMAT_S8:
        plugin.fmt.bps = 8;
        break;
    case SND_PCM_FORMAT_S16_BE:
    case SND_PCM_FORMAT_S16_LE:
        plugin.fmt.bps = 16;
        break;
    case SND_PCM_FORMAT_S24_3BE:
    case SND_PCM_FORMAT_S24_3LE:
        plugin.fmt.bps = 24;
        break;
    case SND_PCM_FORMAT_S32_BE:
    case SND_PCM_FORMAT_S32_LE:
        plugin.fmt.bps = 32;
        break;
    case SND_PCM_FORMAT_FLOAT_LE:
    case SND_PCM_FORMAT_FLOAT_BE:
        plugin.fmt.bps = 32;
        plugin.fmt.is_float = 1;
        break;
    }

    trace ("chosen bps: %d (%s)\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int");

    plugin.fmt.channels = nchan;
    plugin.fmt.channelmask = 0;
    if (nchan == 1) {
        plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT;
    }
    if (nchan == 2) {
        plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT;
    }
    if (nchan == 3) {
        plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_LOW_FREQUENCY;
    }
    if (nchan == 4) {
        plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT;
    }
    if (nchan == 5) {
        plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER;
    }
    if (nchan == 6) {
        plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER | DDB_SPEAKER_LOW_FREQUENCY;
    }
    if (nchan == 7) {
        plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER | DDB_SPEAKER_SIDE_LEFT | DDB_SPEAKER_SIDE_RIGHT;
    }
    if (nchan == 8) {
        plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER | DDB_SPEAKER_SIDE_LEFT | DDB_SPEAKER_SIDE_RIGHT | DDB_SPEAKER_LOW_FREQUENCY;
    }
error:
    if (err < 0) {
        memset (&plugin.fmt, 0, sizeof (ddb_waveformat_t));
    }
    if (hw_params) {
        snd_pcm_hw_params_free (hw_params);
    }
    return err;
}
Example #12
0
/* ------- PCM INITS --------------------------------- */
static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params,int *chs)
{
#ifndef ALSAAPI9
  unsigned int rrate;
  int err, dir;
  int channels_allocated = 0;

  /* choose all parameters */
  err = snd_pcm_hw_params_any(handle, params);
  if (err < 0) {
    check_error(err,"Broken configuration: no configurations available");
    return err;
  }

  /* set the nointerleaved read/write format */
  err = snd_pcm_hw_params_set_access(handle, params,
                                     SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
  if (err >= 0) {
#ifdef ALSAMM_DEBUG
    if(sys_verbose)
      post("Access type %s available","SND_PCM_ACCESS_MMAP_NONINTERLEAVED");
#endif
  }
  else{
    check_error(err,"No Accesstype SND_PCM_ACCESS_MMAP_NONINTERLEAVED");
    return err;
  }

  /* set the sample format */
  err = snd_pcm_hw_params_set_format(handle, params, ALSAMM_FORMAT);
  if (err < 0) {
    check_error(err,"Sample format not available for playback");
    return err;
  }

#ifdef ALSAMM_DEBUG
  if(sys_verbose)
    post("Setting format to %s",snd_pcm_format_name(ALSAMM_FORMAT));
#endif

  /* first check samplerate since channels numbers
     are samplerate dependent (double speed) */
  /* set the stream rate */

  rrate = alsamm_sr;

#ifdef ALSAMM_DEBUG
  if(sys_verbose)
    post("Samplerate request: %i Hz",rrate);
#endif

  dir=-1;
  err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, &dir);
  if (err < 0) {
    check_error(err,"Rate not available");
    return err;
  }

  if (rrate != alsamm_sr) {
    post("Warning: rate %iHz doesn't match requested %iHz", rrate,alsamm_sr);
    alsamm_sr = rrate;
  }
  else
    if(sys_verbose)
      post("Samplerate is set to %iHz",alsamm_sr);

  /* Info on channels */
  {
    int maxchs,minchs,channels = *chs;

    if((err = snd_pcm_hw_params_get_channels_max(params,
        (unsigned int *)&maxchs)) < 0){
      check_error(err,"Getting channels_max not available");
      return err;
    }
    if((err = snd_pcm_hw_params_get_channels_min(params,
        (unsigned int *)&minchs)) < 0){
      check_error(err,"Getting channels_min not available");
      return err;
    }

#ifdef ALSAMM_DEBUG
    if(sys_verbose)
      post("Getting channels:min=%d, max= %d for request=%d",minchs,maxchs,channels);
#endif
    if(channels < 0)channels=maxchs;
    if(channels > maxchs)channels = maxchs;
    if(channels < minchs)channels = minchs;

    if(channels != *chs)
      post("requested channels=%d but used=%d",*chs,channels);

    *chs = channels;
#ifdef ALSAMM_DEBUG
    if(sys_verbose)
      post("trying to use channels: %d",channels);
#endif
  }

  /* set the count of channels */
  err = snd_pcm_hw_params_set_channels(handle, params, *chs);
  if (err < 0) {
    check_error(err,"Channels count not available");
    return err;
  }

  /* testing for channels */
  if((err = snd_pcm_hw_params_get_channels(params,(unsigned int *)chs)) < 0)
    check_error(err,"Get channels not available");
#ifdef ALSAMM_DEBUG
  else
    if(sys_verbose)
      post("When setting channels count and got %d",*chs);
#endif

  /* if buffersize is set use this instead buffertime */
  if(alsamm_buffersize > 0){

#ifdef ALSAMM_DEBUG
    if(sys_verbose)
      post("hw_params: ask for max buffersize of %d samples",
           (unsigned int) alsamm_buffersize );
#endif

    alsamm_buffer_size = alsamm_buffersize;

    err = snd_pcm_hw_params_set_buffer_size_near(handle, params,
        (unsigned long *)&alsamm_buffer_size);
    if (err < 0) {
      check_error(err,"Unable to set max buffer size");
      return err;
    }

  }
  else{
    if(alsamm_buffertime <= 0) /* should never happen, but use 20ms */
      alsamm_buffertime = 20000;

#ifdef ALSAMM_DEBUG
    if(sys_verbose)
      post("hw_params: ask for max buffertime of %d ms",
           (unsigned int) (alsamm_buffertime*0.001) );
#endif

    err = snd_pcm_hw_params_set_buffer_time_near(handle, params,
        &alsamm_buffertime, &dir);
    if (err < 0) {
      check_error(err,"Unable to set max buffer time");
      return err;
    }
  }

  err = snd_pcm_hw_params_get_buffer_time(params,
    (unsigned int *)&alsamm_buffertime, &dir);
  if (err < 0) {
    check_error(err,"Unable to get buffer time");
    return err;
  }

#ifdef ALSAMM_DEBUG
  if(sys_verbose)
    post("hw_params: got buffertime to %f ms",
         (float) (alsamm_buffertime*0.001));
#endif

  err = snd_pcm_hw_params_get_buffer_size(params,
    (unsigned long *)&alsamm_buffer_size);
  if (err < 0) {
    check_error(err,"Unable to get buffer size");
    return err;
  }

#ifdef ALSAMM_DEBUG
  if(sys_verbose)
    post("hw_params: got  buffersize to %d samples",(int) alsamm_buffer_size);
#endif

  err = snd_pcm_hw_params_get_period_size(params,
    (unsigned long *)&alsamm_period_size, &dir);
  if (err > 0) {
    check_error(err,"Unable to get period size");
    return err;
  }

#ifdef ALSAMM_DEBUG
  if(sys_verbose)
    post("Got period size of %d", (int) alsamm_period_size);
#endif
  {
    unsigned int pmin,pmax;

    err = snd_pcm_hw_params_get_periods_min(params, &pmin, &dir);
    if (err > 0) {
      check_error(err,"Unable to get period size");
      return err;
    }
    err = snd_pcm_hw_params_get_periods_min(params, &pmax, &dir);
    if (err > 0) {
      check_error(err,"Unable to get period size");
      return err;
    }

    /* use maximum of periods */
    if( alsamm_periods <= 0)
      alsamm_periods = pmax;
    alsamm_periods = (alsamm_periods > pmax)?pmax:alsamm_periods;
    alsamm_periods = (alsamm_periods < pmin)?pmin:alsamm_periods;

    err = snd_pcm_hw_params_set_periods(handle, params, alsamm_periods, dir);
    if (err > 0) {
      check_error(err,"Unable to set periods");
      return err;
    }


    err = snd_pcm_hw_params_get_periods(params, &pmin, &dir);
    if (err > 0) {
      check_error(err,"Unable to get periods");
      return err;
    }
#ifdef ALSAMM_DEBUG
    if(sys_verbose)
      post("Got periods of %d, where periodsmin=%d, periodsmax=%d",
           alsamm_periods,pmin,pmax);
#endif
  }

  /* write the parameters to device */
  err = snd_pcm_hw_params(handle, params);
  if (err < 0) {
    check_error(err,"Unable to set hw params");
    return err;
  }
#endif /* ALSAAPI9 */
  return 0;
}
Example #13
0
int main( int argc, char *argv[] )
{
    struct structArgs cmdArgs;
	unsigned int val, val2;
	int dir;
    int errNum;
	cmdArgs.card = 0;		// Default card.
	cmdArgs.control = 1;	// Default control.


    // ************************************************************************
    //  ALSA control elements.
    // ************************************************************************
    snd_pcm_t *pcmp;
    snd_pcm_hw_params_t *params;
//	snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
	snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE;
    snd_pcm_uframes_t frames;


    // ************************************************************************
    //  Get command line parameters.
    // ************************************************************************
    argp_parse( &argp, argc, argv, 0, 0, &cmdArgs );

    printf( "Card = %i\n", cmdArgs.card );
    printf( "Control = %i\n", cmdArgs.control );
    sprintf( cmdArgs.deviceID, "hw:%i,%i", cmdArgs.card, cmdArgs.control );
	printf( "Using device %s :", cmdArgs.deviceID );

    /* Allocate a hardware parameters object. */
    if ( snd_pcm_hw_params_alloca( &params ) < 0 )
    {
    	fprintf( stderr, "Unable to allocate.\n" );
    	return -1;
   	}
    /* Open PCM device for playback. */
//    if ( snd_pcm_open( &pcmp, cmdArgs.deviceID, stream, 0 ) < 0 )
//    {
//        fprintf( stderr, "Unable to open pcm device.\n" );
//    	return -1;
//    }
    /* Fill it in with default values. */
//    if ( snd_pcm_hw_params_any( pcmp, params ) < 0
//    {
//    	fprintf( stderr, "Unable to set default values.\n" );
//    	return -1;
//    }
    /* Interleaved mode */
//    snd_pcm_hw_params_set_access( pcmp, params,
//    		SND_PCM_ACCESS_RW_INTERLEAVED );

    /* Signed 16-bit little-endian format */
    snd_pcm_hw_params_set_format( pcmp, params,
        	SND_PCM_FORMAT_S16_LE );

    /* Two channels (stereo) */
    snd_pcm_hw_params_set_channels( pcmp, params, 2 );

    /* 44100 bits/second sampling rate (CD quality) */
    val = 44100;
    snd_pcm_hw_params_set_rate_near( pcmp, params, &val, &dir );

    /* Write the parameters to the driver */
    errNum = snd_pcm_hw_params( pcmp, params );
    if ( errNum < 0 )
    {
        fprintf(stderr, "unable to set hw parameters: %s\n",
            snd_strerror( errNum ));
        exit( 1 );
    }

    /* Display information about the PCM interface */

    printf( "PCM handle name = '%s'\n", snd_pcm_name( pcmp ));

    printf("PCM state = %s\n", snd_pcm_state_name( snd_pcm_state( pcmp )));

    snd_pcm_hw_params_get_access( params, ( snd_pcm_access_t * ) &val );
    printf( "access type = %s\n",
        snd_pcm_access_name(( snd_pcm_access_t ) val ));

    snd_pcm_hw_params_get_format( params, ( snd_pcm_format_t * ) &val );
    printf( "format = '%s' (%s)\n",
        snd_pcm_format_name(( snd_pcm_format_t ) val ),
        snd_pcm_format_description(( snd_pcm_format_t ) val ));

    snd_pcm_hw_params_get_subformat( params,
        ( snd_pcm_subformat_t * ) &val );
    printf( "subformat = '%s' (%s)\n",
        snd_pcm_subformat_name(( snd_pcm_subformat_t ) val ),
        snd_pcm_subformat_description((
        snd_pcm_subformat_t ) val ));

    snd_pcm_hw_params_get_channels( params, &val );
    printf( "channels = %d\n", val );

    snd_pcm_hw_params_get_rate( params, &val, &dir );
    printf( "rate = %d bps\n", val );

    snd_pcm_hw_params_get_period_time( params, &val, &dir );
    printf( "period time = %d us\n", val );

    snd_pcm_hw_params_get_period_size( params, &frames, &dir );
    printf( "period size = %d frames\n", ( int ) frames );

    snd_pcm_hw_params_get_buffer_time( params, &val, &dir );
    printf( "buffer time = %d us\n", val );

    snd_pcm_hw_params_get_buffer_size( params,
        ( snd_pcm_uframes_t * ) &val );
    printf( "buffer size = %d frames\n", val );

    snd_pcm_hw_params_get_periods( params, &val, &dir );
    printf( "periods per buffer = %d frames\n", val );

    snd_pcm_hw_params_get_rate_numden( params, &val, &val2 );
    printf( "exact rate = %d/%d bps\n", val, val2 );

    val = snd_pcm_hw_params_get_sbits( params );
    printf( "significant bits = %d\n", val );

//    snd_pcm_hw_params_get_tick_time( params, &val, &dir );
//    printf( "tick time = %d us\n", val );

    val = snd_pcm_hw_params_is_batch( params );
    printf( "is batch = %d\n", val );

    val = snd_pcm_hw_params_is_block_transfer( params );
    printf( "is block transfer = %d\n", val );

    val = snd_pcm_hw_params_is_double( params );
    printf( "is double = %d\n", val );

    val = snd_pcm_hw_params_is_half_duplex( params );
    printf( "is half duplex = %d\n", val );

    val = snd_pcm_hw_params_is_joint_duplex( params );
    printf( "is joint duplex = %d\n", val );

    val = snd_pcm_hw_params_can_overrange( params );
    printf( "can overrange = %d\n", val );

    val = snd_pcm_hw_params_can_mmap_sample_resolution( params );
    printf( "can mmap = %d\n", val );

    val = snd_pcm_hw_params_can_pause( params );
    printf( "can pause = %d\n", val );

    val = snd_pcm_hw_params_can_resume( params );
    printf( "can resume = %d\n", val );

    val = snd_pcm_hw_params_can_sync_start( params );
    printf( "can sync start = %d\n", val );
    snd_pcm_close( pcmp );

    return 0;
}
Example #14
0
static int
set_params(AudioDevice *ad, AudioFormat *format_p, int *ch_p, unsigned int *rate_p)
{
  ALSA_data *alsa = (ALSA_data *)ad->private_data;
  int r, err;
  snd_pcm_format_t f;
  AudioFormat format = *format_p;
  snd_pcm_hw_params_t *hwparams;
  snd_pcm_sw_params_t *swparams;
  int ch = *ch_p;
  unsigned int rate = *rate_p;
  unsigned int buffer, period;

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

  ad->format = _AUDIO_FORMAT_UNSET;
  *format_p = _AUDIO_FORMAT_UNSET;
  *ch_p = 0;
  *rate_p = 0;

  /* format part */
  switch (format) {
  case _AUDIO_FORMAT_MU_LAW:
    f = SND_PCM_FORMAT_MU_LAW;
    break;
  case _AUDIO_FORMAT_A_LAW:
    f = SND_PCM_FORMAT_A_LAW;
    break;
  case _AUDIO_FORMAT_ADPCM:
    f = SND_PCM_FORMAT_IMA_ADPCM;
    break;
  case _AUDIO_FORMAT_U8:
    f = SND_PCM_FORMAT_U8;
    break;
  case _AUDIO_FORMAT_S8:
    f = SND_PCM_FORMAT_S8;
    break;
  case _AUDIO_FORMAT_U16_LE:
    f = SND_PCM_FORMAT_U16_LE;
    break;
  case _AUDIO_FORMAT_U16_BE:
    f = SND_PCM_FORMAT_U16_BE;
    break;
  case _AUDIO_FORMAT_S16_LE:
    f = SND_PCM_FORMAT_S16_LE;
    break;
  case _AUDIO_FORMAT_S16_BE:
    f = SND_PCM_FORMAT_S16_BE;
    break;
#if 0
  case _AUDIO_FORMAT_S32_LE:
    f = SND_PCM_FORMAT_U32_LE;
    break;
  case _AUDIO_FORMAT_S32_BE:
    f = SND_PCM_FORMAT_S32_BE;
    break;
#endif
  default:
    show_message_fnc("format %d is invalid.\n", format);
    return 0;
  }

  if ((err = snd_pcm_hw_params_any(alsa->fd, hwparams)) < 0) {
    show_message_fnc("snd_pcm_hw_params_any() failed.\n");
    return 0;
  }

  if ((err = snd_pcm_hw_params_set_access(alsa->fd, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
    show_message_fnc("snd_pcm_hw_params_set_access() failed.\n");
    return 0;
  }

  if ((err = snd_pcm_hw_params_set_format(alsa->fd, hwparams, f)) < 0) {
    show_message_fnc("snd_pcm_hw_params_set_format() failed.\n");
    return 0;
  }
  ad->format = format;
  *format_p = format;

  /* channel part */
  if ((err = snd_pcm_hw_params_set_channels(alsa->fd, hwparams, ch)) < 0) {
    show_message_fnc("snd_pcm_hw_params_set_channels() failed.\n");
    return 0;
  }
  *ch_p = ch;

  /* rate part */
  if ((err = snd_pcm_hw_params_set_rate_near(alsa->fd, hwparams, &rate, 0)) < 0) {
    show_message_fnc("snd_pcm_hw_params_set_rate_near() failed.\n");
    return 0;
  }
  *rate_p = rate;

  /* buffer & period */
  buffer = 500000;
  period = 500000 / 4;
  if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa->fd, hwparams, &buffer, 0)) < 0) {
    show_message_fnc("snd_pcm_hw_params_set_buffer_near() failed.\n");
    return 0;
  }
  r = snd_pcm_hw_params_get_buffer_size(hwparams, &alsa->buffer_size);
  if ((err = snd_pcm_hw_params_set_period_time_near(alsa->fd, hwparams, &period, 0)) < 0) {
    show_message_fnc("snd_pcm_hw_params_set_period_near() failed.\n");
    return 0;
  }
  r = snd_pcm_hw_params_get_period_size(hwparams, &alsa->period_size, 0);

  if ((err = snd_pcm_hw_params(alsa->fd, hwparams)) < 0) {
    perror("snd_pcm_hw_params");
    err_message_fnc("snd_pcm_hw_params() failed.\n");
    snd_pcm_hw_params_dump(hwparams, alsa->log);
    return 0;
  }

  r = snd_pcm_hw_params_get_channels(hwparams, &ad->channels);
  r = snd_pcm_hw_params_get_rate(hwparams, &ad->speed, 0);
  r = r; // dummy

#ifdef DEBUG
  {
    snd_pcm_format_t form;

    debug_message_fnc("format ");
    r = snd_pcm_hw_params_get_format(hwparams, &form);
    switch (form) {
    case SND_PCM_FORMAT_MU_LAW:    debug_message("MU_LAW "); break;
    case SND_PCM_FORMAT_A_LAW:     debug_message("A_LAW "); break;
    case SND_PCM_FORMAT_IMA_ADPCM: debug_message("ADPCM "); break;
    case SND_PCM_FORMAT_U8:        debug_message("U8 "); break;
    case SND_PCM_FORMAT_S8:        debug_message("S8 "); break;
    case SND_PCM_FORMAT_U16_LE:    debug_message("U16LE "); break;
    case SND_PCM_FORMAT_U16_BE:    debug_message("U16BE "); break;
    case SND_PCM_FORMAT_S16_LE:    debug_message("S16LE "); break;
    case SND_PCM_FORMAT_S16_BE:    debug_message("S16BE "); break;
#if 0
    case SND_PCM_FORMAT_U32_LE:    debug_message("U32LE "); break;
    case SND_PCM_FORMAT_S32_BE:    debug_message("S32BE "); break;
#endif
    default:                       debug_message("UNKNOWN "); break;
    }

    debug_message("%d ch %d Hz buffer %ld period %ld OK\n", ad->channels, ad->speed, alsa->buffer_size, alsa->period_size);
  }
#endif

  /* sw_params */
  if ((err = snd_pcm_sw_params_current(alsa->fd, swparams)) < 0) {
    show_message_fnc("snd_pcm_sw_params_any() failed.\n");
    return 0;
  }
  if ((err = snd_pcm_sw_params(alsa->fd, swparams)) < 0) {
    show_message_fnc("snd_pcm_sw_params() failed.\n");
    return 0;
  }

  debug_message_fnc("1 sample -> %ld bytes\n", snd_pcm_samples_to_bytes(alsa->fd, 1));

  return 1;
}
Example #15
0
/**************************************************************************
 * 			ALSA_TraceParameters		[internal]
 *
 * used to trace format changes, hw and sw parameters
 */
void ALSA_TraceParameters(snd_pcm_hw_params_t * hw_params, snd_pcm_sw_params_t * sw, int full)
{
    int err;
    snd_pcm_format_t   format;
    snd_pcm_access_t   access;

#define X(x) ((x)? "true" : "false")
    if (full)
	TRACE("FLAGS: sampleres=%s overrng=%s pause=%s resume=%s syncstart=%s batch=%s block=%s double=%s "
	      "halfd=%s joint=%s\n",
	      X(snd_pcm_hw_params_can_mmap_sample_resolution(hw_params)),
	      X(snd_pcm_hw_params_can_overrange(hw_params)),
	      X(snd_pcm_hw_params_can_pause(hw_params)),
	      X(snd_pcm_hw_params_can_resume(hw_params)),
	      X(snd_pcm_hw_params_can_sync_start(hw_params)),
	      X(snd_pcm_hw_params_is_batch(hw_params)),
	      X(snd_pcm_hw_params_is_block_transfer(hw_params)),
	      X(snd_pcm_hw_params_is_double(hw_params)),
	      X(snd_pcm_hw_params_is_half_duplex(hw_params)),
	      X(snd_pcm_hw_params_is_joint_duplex(hw_params)));
#undef X

    err = snd_pcm_hw_params_get_access(hw_params, &access);
    if (err >= 0)
    {
	TRACE("access=%s\n", snd_pcm_access_name(access));
    }
    else
    {
	snd_pcm_access_mask_t * acmask;

        acmask = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_pcm_access_mask_sizeof());
	snd_pcm_hw_params_get_access_mask(hw_params, acmask);
	for ( access = SND_PCM_ACCESS_MMAP_INTERLEAVED; access <= SND_PCM_ACCESS_LAST; access++)
	    if (snd_pcm_access_mask_test(acmask, access))
		TRACE("access=%s\n", snd_pcm_access_name(access));
        HeapFree( GetProcessHeap(), 0, acmask );
    }

    err = snd_pcm_hw_params_get_format(hw_params, &format);
    if (err >= 0)
    {
	TRACE("format=%s\n", snd_pcm_format_name(format));

    }
    else
    {
	snd_pcm_format_mask_t *     fmask;

        fmask = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_pcm_format_mask_sizeof());
	snd_pcm_hw_params_get_format_mask(hw_params, fmask);
	for ( format = SND_PCM_FORMAT_S8; format <= SND_PCM_FORMAT_LAST ; format++)
	    if ( snd_pcm_format_mask_test(fmask, format) )
		TRACE("format=%s\n", snd_pcm_format_name(format));
        HeapFree( GetProcessHeap(), 0, fmask );
    }

    do {
      int err=0;
      unsigned int val=0;
      err = snd_pcm_hw_params_get_channels(hw_params, &val);
      if (err<0) {
        unsigned int min = 0;
        unsigned int max = 0;
        err = snd_pcm_hw_params_get_channels_min(hw_params, &min),
	err = snd_pcm_hw_params_get_channels_max(hw_params, &max);
        TRACE("channels_min=%u, channels_min_max=%u\n", min, max);
      } else {
        TRACE("channels=%d\n", val);
      }
    } while(0);
    do {
      int err=0;
      snd_pcm_uframes_t val=0;
      err = snd_pcm_hw_params_get_buffer_size(hw_params, &val);
      if (err<0) {
        snd_pcm_uframes_t min = 0;
        snd_pcm_uframes_t max = 0;
        err = snd_pcm_hw_params_get_buffer_size_min(hw_params, &min),
	err = snd_pcm_hw_params_get_buffer_size_max(hw_params, &max);
        TRACE("buffer_size_min=%lu, buffer_size_min_max=%lu\n", min, max);
      } else {
        TRACE("buffer_size=%lu\n", val);
      }
    } while(0);

#define X(x) do { \
int err=0; \
int dir=0; \
unsigned int val=0; \
err = snd_pcm_hw_params_get_##x(hw_params,&val, &dir); \
if (err<0) { \
  unsigned int min = 0; \
  unsigned int max = 0; \
  err = snd_pcm_hw_params_get_##x##_min(hw_params, &min, &dir); \
  err = snd_pcm_hw_params_get_##x##_max(hw_params, &max, &dir); \
  TRACE(#x "_min=%u " #x "_max=%u\n", min, max); \
} else \
    TRACE(#x "=%d\n", val); \
} while(0)

    X(rate);
    X(buffer_time);
    X(periods);
    do {
      int err=0;
      int dir=0;
      snd_pcm_uframes_t val=0;
      err = snd_pcm_hw_params_get_period_size(hw_params, &val, &dir);
      if (err<0) {
        snd_pcm_uframes_t min = 0;
        snd_pcm_uframes_t max = 0;
        err = snd_pcm_hw_params_get_period_size_min(hw_params, &min, &dir),
	err = snd_pcm_hw_params_get_period_size_max(hw_params, &max, &dir);
        TRACE("period_size_min=%lu, period_size_min_max=%lu\n", min, max);
      } else {
        TRACE("period_size=%lu\n", val);
      }
    } while(0);

    X(period_time);
#undef X

    if (!sw)
	return;
}
static int bluetooth_a2dp_init(struct bluetooth_data *data,
					snd_pcm_hw_params_t *params)
{
	struct bluetooth_alsa_config *cfg = &data->alsa_config;
	sbc_capabilities_t *cap = &data->a2dp.sbc_capabilities;
	unsigned int max_bitpool, min_bitpool, rate, channels;
	int dir;

	snd_pcm_hw_params_get_rate(params, &rate, &dir);
	snd_pcm_hw_params_get_channels(params, &channels);

	switch (rate) {
	case 48000:
		cap->frequency = BT_SBC_SAMPLING_FREQ_48000;
		break;
	case 44100:
		cap->frequency = BT_SBC_SAMPLING_FREQ_44100;
		break;
	case 32000:
		cap->frequency = BT_SBC_SAMPLING_FREQ_32000;
		break;
	case 16000:
		cap->frequency = BT_SBC_SAMPLING_FREQ_16000;
		break;
	default:
		DBG("Rate %d not supported", rate);
		return -1;
	}

	if (cfg->has_channel_mode)
		cap->channel_mode = cfg->channel_mode;
	else if (channels == 2) {
		if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO)
			cap->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
		else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO)
			cap->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO;
		else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL)
			cap->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
	} else {
		if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
			cap->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
	}

	if (!cap->channel_mode) {
		DBG("No supported channel modes");
		return -1;
	}

	if (cfg->has_block_length)
		cap->block_length = cfg->block_length;
	else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_16)
		cap->block_length = BT_A2DP_BLOCK_LENGTH_16;
	else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_12)
		cap->block_length = BT_A2DP_BLOCK_LENGTH_12;
	else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_8)
		cap->block_length = BT_A2DP_BLOCK_LENGTH_8;
	else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_4)
		cap->block_length = BT_A2DP_BLOCK_LENGTH_4;
	else {
		DBG("No supported block lengths");
		return -1;
	}

	if (cfg->has_subbands)
		cap->subbands = cfg->subbands;
	if (cap->subbands & BT_A2DP_SUBBANDS_8)
		cap->subbands = BT_A2DP_SUBBANDS_8;
	else if (cap->subbands & BT_A2DP_SUBBANDS_4)
		cap->subbands = BT_A2DP_SUBBANDS_4;
	else {
		DBG("No supported subbands");
		return -1;
	}

	if (cfg->has_allocation_method)
		cap->allocation_method = cfg->allocation_method;
	if (cap->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS)
		cap->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS;
	else if (cap->allocation_method & BT_A2DP_ALLOCATION_SNR)
		cap->allocation_method = BT_A2DP_ALLOCATION_SNR;

	if (cfg->has_bitpool)
		min_bitpool = max_bitpool = cfg->bitpool;
	else {
		min_bitpool = MAX(MIN_BITPOOL, cap->min_bitpool);
		max_bitpool = MIN(default_bitpool(cap->frequency,
					cap->channel_mode),
					cap->max_bitpool);
	}

	cap->min_bitpool = min_bitpool;
	cap->max_bitpool = max_bitpool;

	return 0;
}
Example #17
0
int main()
{
    long loops;
    int rc,i = 0;
    int size;
    FILE *fp ;
    snd_pcm_t *handle;
    snd_pcm_hw_params_t *params;
    unsigned int val,val2;
    int dir;
    snd_pcm_uframes_t frames;
    char *buffer;
    if(  (fp =fopen("sound.wav","w")) < 0)
        printf("open sound.wav fial\n");
    /* Open PCM device for recording (capture). */
    rc = snd_pcm_open(&handle, "default",
                      SND_PCM_STREAM_CAPTURE, 0);
    if (rc < 0)
    {
        fprintf(stderr,  "unable to open pcm device: %s/n",  snd_strerror(rc));
        exit(1);
    }
    /* Allocate a hardware parameters object. */
    snd_pcm_hw_params_alloca(&params);
    /* Fill it in with default values. */
    snd_pcm_hw_params_any(handle, params);
    /* Set the desired hardware parameters. */
    /* Interleaved mode */
    snd_pcm_hw_params_set_access(handle, params,
                                 SND_PCM_ACCESS_RW_INTERLEAVED);
    /* Signed 16-bit little-endian format */
    snd_pcm_hw_params_set_format(handle, params,
                                 SND_PCM_FORMAT_S16_LE);
    /* Two channels (stereo) */
    snd_pcm_hw_params_set_channels(handle, params, 2);
    /* 44100 bits/second sampling rate (CD quality) */
    val = 44100;
    snd_pcm_hw_params_set_rate_near(handle, params,  &val, &dir);
    /* Set period size to 32 frames. */
    frames = 32;
    snd_pcm_hw_params_set_period_size_near(handle,  params, &frames, &dir);
    /* Write the parameters to the driver */
    rc = snd_pcm_hw_params(handle, params);
    if (rc < 0)
    {
        fprintf(stderr,  "unable to set hw parameters: %s/n",
                snd_strerror(rc));
        exit(1);
    }
    /* Use a buffer large enough to hold one period */
    snd_pcm_hw_params_get_period_size(params,  &frames, &dir);
    size = frames * 4; /* 2 bytes/sample, 2 channels */
    printf("size = %d\n",size);
    buffer = (char *) malloc(size);
    /* We want to loop for 5 seconds */
    snd_pcm_hw_params_get_period_time(params,  &val, &dir);
    loops = 10000000 / val;
    while (loops > 0)
    {
        loops--;
        rc = snd_pcm_readi(handle, buffer, frames);
        printf("%d\n",i++);
        if (rc == -EPIPE)
        {
            /* EPIPE means overrun */
            fprintf(stderr, "overrun occurred/n");
            snd_pcm_prepare(handle);
        }
        else if (rc < 0)
        {
            fprintf(stderr,
                    "error from read: %s/n",
                    snd_strerror(rc));
        }
        else if (rc != (int)frames)
        {
            fprintf(stderr, "short read, read %d frames/n", rc);
        }
//rc = fwrite( buffer,1, size,fp);
        rc = write(1,buffer,size);
        if (rc != size)
            fprintf(stderr,  "short write: wrote %d bytes/n", rc);
        else printf("fwrite buffer success\n");
    }
    /******************打印参数*********************/
    snd_pcm_hw_params_get_channels(params, &val);
    printf("channels = %d\n", val);
    snd_pcm_hw_params_get_rate(params, &val, &dir);
    printf("rate = %d bps\n", val);
    snd_pcm_hw_params_get_period_time(params,
                                      &val, &dir);
    printf("period time = %d us\n", val);
    snd_pcm_hw_params_get_period_size(params,
                                      &frames, &dir);
    printf("period size = %d frames\n", (int)frames);
    snd_pcm_hw_params_get_buffer_time(params,
                                      &val, &dir);
    printf("buffer time = %d us\n", val);
    snd_pcm_hw_params_get_buffer_size(params,
                                      (snd_pcm_uframes_t *) &val);
    printf("buffer size = %d frames\n", val);
    snd_pcm_hw_params_get_periods(params, &val, &dir);
    printf("periods per buffer = %d frames\n", val);
    snd_pcm_hw_params_get_rate_numden(params,
                                      &val, &val2);
    printf("exact rate = %d/%d bps\n", val, val2);
    val = snd_pcm_hw_params_get_sbits(params);
    printf("significant bits = %d\n", val);
//snd_pcm_hw_params_get_tick_time(params,  &val, &dir);
    printf("tick time = %d us\n", val);
    val = snd_pcm_hw_params_is_batch(params);
    printf("is batch = %d\n", val);
    val = snd_pcm_hw_params_is_block_transfer(params);
    printf("is block transfer = %d\n", val);
    val = snd_pcm_hw_params_is_double(params);
    printf("is double = %d\n", val);
    val = snd_pcm_hw_params_is_half_duplex(params);
    printf("is half duplex = %d\n", val);
    val = snd_pcm_hw_params_is_joint_duplex(params);
    printf("is joint duplex = %d\n", val);
    val = snd_pcm_hw_params_can_overrange(params);
    printf("can overrange = %d\n", val);
    val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
    printf("can mmap = %d\n", val);
    val = snd_pcm_hw_params_can_pause(params);
    printf("can pause = %d\n", val);
    val = snd_pcm_hw_params_can_resume(params);
    printf("can resume = %d\n", val);
    val = snd_pcm_hw_params_can_sync_start(params);
    printf("can sync start = %d\n", val);
    /*******************************************************************/
    snd_pcm_drain(handle);
    snd_pcm_close(handle);
    fclose(fp);
    free(buffer);
    return 0;

}
Example #18
0
int main() {
  int result;
  snd_pcm_t *handle = NULL;
  snd_pcm_hw_params_t *params = NULL;
  snd_pcm_uframes_t frames;
  snd_pcm_access_t access;
  snd_pcm_format_t format;
  unsigned int rate = 44100;
  unsigned int val, val2;
  int dir = 0;
const char           *device = getenv ("ALSA_DEFAULT");
  if (device == NULL) {
    device = "default";
  }
  result = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0);
  if (result < 0) 
    showErrorAndExit(result, "Error: Unable to open PCM device: %s\n");
  result = snd_pcm_hw_params_malloc(&params);
  if (result < 0) 
    showErrorAndExit(result, "Error: No memory for hardware parameters: %s\n");
  result = snd_pcm_hw_params_any(handle, params);
  if (result < 0) 
    showErrorAndExit(result, "Error: Cannot read HW params: %s\n");
  result = snd_pcm_hw_params_set_access(handle, params,
                                        SND_PCM_ACCESS_RW_INTERLEAVED);
  if (result < 0)
    showErrorAndExit(result, "Could not set access method: %s\n");
  result = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
  if (result < 0)
    showErrorAndExit(result, "Error: Could not set output format: %s\n");
  result = snd_pcm_hw_params_set_channels(handle, params, 1);
  if (result < 0)
    showErrorAndExit(result, "Error: Cannot set to 1 channel: %s\n");
  result = snd_pcm_hw_params_set_rate_near(handle, params, &rate, &dir);
  if (result < 0)
    showErrorAndExit(result, "Error: Could not set rate: %s\n");
  result = snd_pcm_hw_params(handle, params);
  if (result < 0)
    showErrorAndExit(result, "Error: Could not write HW params: %s\n");
  printf("Card Parameters\n");
  printf("%30s: %s\n", "Alsa Library Version", snd_asoundlib_version());
  result = snd_pcm_hw_params_get_access(params, &access);
  if (result < 0) {
    showErrorAndExit(result, "Error: Could not retrieve access mode: %s\n");
  } else {
    printf("%30s: %s\n", "Access Method", snd_pcm_access_name(access));
  }
  result = snd_pcm_hw_params_get_format(params, &format);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve format type: %d\n");
  } else {
    printf("%30s: %s\n", "Format", snd_pcm_format_name(format));
  }
  result = snd_pcm_hw_params_get_channels(params, &val);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve channel count: %s\n");
  } else {
    printf("%30s: %d\n", "Channels", val);
  }
  result = snd_pcm_hw_params_get_rate(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve rate: %s\n");
  } else {
    printf("%30s: %d bps\n", "Rate", val);
  }
  result = snd_pcm_hw_params_get_period_time(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve period time: %s\n");
  } else {
    printf("%30s: %d us\n", "Period Time", val);
  }
  result = snd_pcm_hw_params_get_period_size(params, &frames, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve period size: %s\n");
  } else {
    printf("%30s: %d frames\n", "Period Size", (int) frames);
  }
  result = snd_pcm_hw_params_get_buffer_time(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve buffer time: %s\n");
  } else {
    printf("%30s: %d us\n", "Buffer Time", val);
  }
  result = snd_pcm_hw_params_get_buffer_size(params, &frames);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to retrieve buffer size: %s\n");
  } else {
    printf("%30s: %d frames\n", "Buffer Size", (int) frames);
  }
  result = snd_pcm_hw_params_get_periods(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to get buffer periods: %s\n");
  } else {
    printf("%30s: %d frames\n", "Periods per Buffer", val);
  }
  result = snd_pcm_hw_params_get_rate_numden(params, &val, &val2);
  if (result < 0) {
    showErrorAndExit(result, "Error: Unable to get rate numerator/denominator: %s\n");
  } else {
    printf("%30s: %d/%d bps\n", "Exact Rate", val, val2);
  }
  val = snd_pcm_hw_params_get_sbits(params);
  printf("%30s: %d\n", "Significant Bits", val);
  result = snd_pcm_hw_params_get_tick_time(params, &val, &dir);
  if (result < 0) {
    showErrorAndExit(result, "Error: Could not retrieve tick time: %s\n");
  } else {
    printf("%30s: %d\n", "Tick Time", val);
  }
  printf("Card Capabilities\n");
  val = snd_pcm_hw_params_is_batch(params);
  printf("%30s: %s\n", "Batch Transfer", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_is_block_transfer(params);
  printf("%30s: %s\n", "Block Transfer", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_is_double(params);
  printf("%30s: %s\n", "Double Buffering", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_is_half_duplex(params);
  printf("%30s: %s\n", "Half Duplex Only", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_is_joint_duplex(params);
  printf("%30s: %s\n", "Joint Duplex Capable", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_overrange(params);
  printf("%30s: %s\n", "Support Overrange Detection", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
  printf("%30s: %s\n", "Support Sample-res Mmap", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_pause(params);
  printf("%30s: %s\n", "Can Pause", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_resume(params);
  printf("%30s: %s\n", "Can Resume", (val ? "Yes" : "No"));
  val = snd_pcm_hw_params_can_sync_start(params);
  printf("%30s: %s\n", "Support Sync Start", (val ? "Yes" : "No"));
  result = snd_pcm_close(handle);
  if (result < 0) 
    showErrorAndExit(result, "Error: Could not close PCM device: %s\n");
  return 0;
}
Example #19
0
int open_alsa_read(struct pcm **p, char *name)
{
	snd_pcm_t *pcm;
	if (snd_pcm_open(&pcm, name, SND_PCM_STREAM_CAPTURE, 0) < 0) {
		fprintf(stderr, "Error opening PCM device %s\n", name);
		return 0;
	}

	snd_pcm_hw_params_t *params;
	snd_pcm_hw_params_alloca(&params);
	if (snd_pcm_hw_params_any(pcm, params) < 0) {
		fprintf(stderr, "Can not configure this PCM device.\n");
		snd_pcm_close(pcm);
		return 0;
	}

	if (snd_pcm_hw_params_set_access(pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
		fprintf(stderr, "Error setting access.\n");
		snd_pcm_close(pcm);
		return 0;
	}

	if (snd_pcm_hw_params_set_format(pcm, params, SND_PCM_FORMAT_S16_LE) < 0) {
		fprintf(stderr, "Error setting S16_LE format.\n");
		snd_pcm_close(pcm);
		return 0;
	}

	if (snd_pcm_hw_params_set_rate_resample(pcm, params, 0) < 0) {
		fprintf(stderr, "Error disabling resampling.\n");
		snd_pcm_close(pcm);
		return 0;
	}

	unsigned rate_min = 8000;
	int dir_min = 0;
	if (snd_pcm_hw_params_set_rate_min(pcm, params, &rate_min, &dir_min) < 0 || rate_min < 8000) {
		fprintf(stderr, "Error setting min rate.\n");
		snd_pcm_close(pcm);
		return 0;
	}

	if (snd_pcm_hw_params(pcm, params) < 0) {
		fprintf(stderr, "Error setting HW params.\n");
		snd_pcm_close(pcm);
		return 0;
	}
	unsigned int rate = 0;
	if (snd_pcm_hw_params_get_rate(params, &rate, 0) < 0) {
		fprintf(stderr, "Error getting rate.\n");
		snd_pcm_close(pcm);
		return 0;
	}
	unsigned int channels = 0;
	if (snd_pcm_hw_params_get_channels(params, &channels) < 0) {
		fprintf(stderr, "Error getting channels.\n");
		snd_pcm_close(pcm);
		return 0;
	}

	struct alsa *alsa = (struct alsa *)malloc(sizeof(struct alsa));
	alsa->base.close = close_alsa;
	alsa->base.info = info_alsa;
	alsa->base.rate = rate_alsa;
	alsa->base.channels = channels_alsa;
	alsa->base.rw = read_alsa;
	alsa->base.data = (void *)alsa;

	alsa->pcm = pcm;
	alsa->r = rate;
	alsa->c = channels;
	alsa->frames = 0;
	*p = &(alsa->base);
	return 1;
}
Example #20
0
/**
 * Allocate the memory-mapped buffer for direct sound, and set up the
 * callback.
 */
static int DSDB_CreateMMAP(IDsDriverBufferImpl* pdbi)
{
    snd_pcm_t *pcm = pdbi->pcm;
    snd_pcm_format_t format;
    snd_pcm_uframes_t frames, ofs, avail, psize, boundary;
    unsigned int channels, bits_per_sample, bits_per_frame;
    int err, mmap_mode;
    const snd_pcm_channel_area_t *areas;
    snd_pcm_hw_params_t *hw_params = pdbi->hw_params;
    snd_pcm_sw_params_t *sw_params = pdbi->sw_params;
    void *buf;

    mmap_mode = snd_pcm_type(pcm);

    if (mmap_mode == SND_PCM_TYPE_HW)
        TRACE("mmap'd buffer is a direct hardware buffer.\n");
    else if (mmap_mode == SND_PCM_TYPE_DMIX)
        TRACE("mmap'd buffer is an ALSA dmix buffer\n");
    else
        TRACE("mmap'd buffer is an ALSA type %d buffer\n", mmap_mode);

    err = snd_pcm_hw_params_get_period_size(hw_params, &psize, NULL);

    err = snd_pcm_hw_params_get_format(hw_params, &format);
    err = snd_pcm_hw_params_get_buffer_size(hw_params, &frames);
    err = snd_pcm_hw_params_get_channels(hw_params, &channels);
    bits_per_sample = snd_pcm_format_physical_width(format);
    bits_per_frame = bits_per_sample * channels;

    if (TRACE_ON(dsalsa))
        ALSA_TraceParameters(hw_params, NULL, FALSE);

    TRACE("format=%s  frames=%ld  channels=%d  bits_per_sample=%d  bits_per_frame=%d\n",
          snd_pcm_format_name(format), frames, channels, bits_per_sample, bits_per_frame);

    pdbi->mmap_buflen_frames = frames;
    pdbi->mmap_buflen_bytes = snd_pcm_frames_to_bytes( pcm, frames );

    snd_pcm_sw_params_current(pcm, sw_params);
    snd_pcm_sw_params_set_start_threshold(pcm, sw_params, 0);
    snd_pcm_sw_params_get_boundary(sw_params, &boundary);
    snd_pcm_sw_params_set_stop_threshold(pcm, sw_params, boundary);
    snd_pcm_sw_params_set_silence_threshold(pcm, sw_params, boundary);
    snd_pcm_sw_params_set_silence_size(pcm, sw_params, 0);
    snd_pcm_sw_params_set_avail_min(pcm, sw_params, 0);
    err = snd_pcm_sw_params(pcm, sw_params);

    avail = snd_pcm_avail_update(pcm);
    if ((snd_pcm_sframes_t)avail < 0)
    {
        ERR("No buffer is available: %s.\n", snd_strerror(avail));
        return DSERR_GENERIC;
    }

    if (!pdbi->mmap)
    {
        buf = pdbi->mmap_buffer = HeapAlloc(GetProcessHeap(), 0, pdbi->mmap_buflen_bytes);
        if (!buf)
            return DSERR_OUTOFMEMORY;

        snd_pcm_format_set_silence(format, buf, pdbi->mmap_buflen_frames);
        pdbi->mmap_pos = 0;
    }
    else
    {
        err = snd_pcm_mmap_begin(pcm, &areas, &ofs, &avail);
        if ( err < 0 )
        {
            ERR("Can't map sound device for direct access: %s/%d\n", snd_strerror(err), err);
            return DSERR_GENERIC;
        }
        snd_pcm_format_set_silence(format, areas->addr, pdbi->mmap_buflen_frames);
        pdbi->mmap_pos = ofs + snd_pcm_mmap_commit(pcm, ofs, 0);
        pdbi->mmap_buffer = areas->addr;
    }

    TRACE("created mmap buffer of %ld frames (%d bytes) at %p\n",
        frames, pdbi->mmap_buflen_bytes, pdbi->mmap_buffer);

    return DS_OK;
}
Example #21
0
int sndout_alsa_start(int rate_, int stereo)
{
	snd_pcm_hw_params_t *hwparams = NULL;
	unsigned int rate = rate_;
	int samples, shift;
	int ret;

	samples = rate * 40 / 1000;
	for (shift = 8; (1 << shift) < samples; shift++)
		;
	period_size = 1 << shift;
	buffer_size = 8 * period_size;

	snd_pcm_hw_params_alloca(&hwparams);

	ret  = snd_pcm_hw_params_any(handle, hwparams);
	ret |= snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
	ret |= snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16_LE);
	ret |= snd_pcm_hw_params_set_channels(handle, hwparams, stereo ? 2 : 1);
	ret |= snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, 0);
	ret |= snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
	ret |= snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, NULL);

	if (ret != 0) {
		fprintf(stderr, PFX "failed to set hwparams\n");
		goto fail;
	}

	ret = snd_pcm_hw_params(handle, hwparams);
	if (ret != 0) {
		fprintf(stderr, PFX "failed to apply hwparams: %d\n", ret);
		goto fail;
	}

	snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
	snd_pcm_hw_params_get_period_size(hwparams, &period_size, NULL);
	snd_pcm_hw_params_get_channels(hwparams, &channels);

	silent_period = realloc(silent_period, period_size * 2 * channels);
	if (silent_period != NULL)
		memset(silent_period, 0, period_size * 2 * channels);

	ret = snd_pcm_prepare(handle);
	if (ret != 0) {
		fprintf(stderr, PFX "snd_pcm_prepare failed: %d\n", ret);
		goto fail;
	}

	ret = snd_pcm_start(handle);
	if (ret != 0) {
		fprintf(stderr, PFX "snd_pcm_start failed: %d\n", ret);
		goto fail;
	}

	failure_counter = 0;

	return 0;

fail:
	// to flush out redirected logs
	fflush(stdout);
	fflush(stderr);
	return -1;
}
Example #22
0
bool QAudioInputPrivate::open( QObject *input )
{
    // Open the Alsa capture device.
    bool    rc = true;
    int     err;

    unsigned int        freakuency = frequency;

    if ((err = snd_pcm_open(&handle,
                             m_device.constData(), //"plughw:0,0"
                             SND_PCM_STREAM_CAPTURE,
                                 0/*SND_PCM_ASYNC*/)) < 0) {

        qWarning( "QAudioInput: snd_pcm_open: error %d", err);

        rc = false;
    }
    else {
        snd_pcm_hw_params_t *hwparams;

        // We want non-blocking mode.
        snd_pcm_nonblock(handle, 1);

        // Set the desired parameters.
        snd_pcm_hw_params_alloca(&hwparams);

        err = snd_pcm_hw_params_any(handle, hwparams);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_hw_params_any: err %d", err);
        }

        err = snd_pcm_hw_params_set_access(handle, hwparams,
                                           access);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_hw_params_set_access: err %d",err);
        }

        err = snd_pcm_hw_params_set_format(handle, hwparams,format);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_hw_params_set_format: err %d",err);
        }

        err = snd_pcm_hw_params_set_channels(handle,hwparams,(unsigned int)channels);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_hw_params_set_channels: err %d",err);
        }

        err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &freakuency, 0);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_hw_params_set_rate_near: err %d",err);
        }
        if(freakuency > 1.05 * frequency || freakuency < 0.95 * frequency) {
            qWarning("QAudioInput: warning, sample rate %i not supported by the hardware, using %u", frequency, freakuency);
        }

        if ( samplesPerBlock != -1 ) {
            // Set buffer and period sizes based on the supplied block size.
            sample_size = (snd_pcm_uframes_t)( samplesPerBlock * channels / 8 );
            err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &freakuency, 0);
            if ( err < 0 ) {
                qWarning( "QAudioInput: snd_pcm_hw_params_set_rate_near: err %d",err);
            }
            if(freakuency > 1.05 * frequency || freakuency < 0.95 * frequency) {
                qWarning( "QAudioInput: warning, sample rate %i not supported by the hardware, using %u", frequency, freakuency);
            }

            err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0);
            if ( err < 0 ) {
                qWarning( "QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err %d",err);
            }
            period_time = 1000000 * 256 / frequency;
            err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0);
            if ( err < 0 ) {
                qWarning( "QAudioInput: snd_pcm_hw_params_set_period_time_near: err %d",err);
            }
        } else {
            // Use the largest buffer and period sizes we can.
            err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0);
            if ( err < 0 ) {
                qWarning( "QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err %d",err);
            }
            period_time = 1000000 * 256 / frequency;
            err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0);
            if ( err < 0 ) {
                qWarning( "QAudioInput: snd_pcm_hw_params_set_period_time_near: err %d",err);
            }
       }

        err = snd_pcm_hw_params(handle, hwparams);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_hw_params: err %d",err);
        }

        int                  dir;
        unsigned int         vval, vval2;
        snd_pcm_access_t     aval;
        snd_pcm_format_t     fval;
        snd_pcm_subformat_t  sval;

        qLog(QAudioInput) << "PCM handle name = " << snd_pcm_name(handle);
        qLog(QAudioInput) << "PCM state = " << snd_pcm_state_name(snd_pcm_state(handle));

        snd_pcm_hw_params_get_access(hwparams,&aval);
        vval = (unsigned int)aval;
        if ( (int)vval != (int)access ) {
            qLog(QAudioInput) << QString("access type not set, want %1 got %2")
                       .arg(snd_pcm_access_name((snd_pcm_access_t)access))
                       .arg(snd_pcm_access_name((snd_pcm_access_t)vval));
            access = (snd_pcm_access_t)vval;
        }
        qLog(QAudioInput) << "access type = " << snd_pcm_access_name((snd_pcm_access_t)vval);

        snd_pcm_hw_params_get_format(hwparams, &fval);
        vval = (unsigned int)fval;
        if ( (int)vval != (int)format ) {
            qLog(QAudioInput) << QString("format type not set, want %1 got %2")
                       .arg(snd_pcm_format_name((snd_pcm_format_t)format))
                       .arg(snd_pcm_format_name((snd_pcm_format_t)vval));
            format = (snd_pcm_format_t)vval;
        }
        qLog(QAudioInput) << QString("format = '%1' (%2)")
            .arg(snd_pcm_format_name((snd_pcm_format_t)vval))
            .arg(snd_pcm_format_description((snd_pcm_format_t)vval))
            .toLatin1().constData();

        snd_pcm_hw_params_get_subformat(hwparams,&sval);
        vval = (unsigned int)sval;
        qLog(QAudioInput) << QString("subformat = '%1' (%2)")
            .arg(snd_pcm_subformat_name((snd_pcm_subformat_t)vval))
            .arg(snd_pcm_subformat_description((snd_pcm_subformat_t)vval))
            .toLatin1().constData();

        snd_pcm_hw_params_get_channels(hwparams, &vval);
        if ( (int)vval != (int)channels ) {
            qLog(QAudioInput) << QString("channels type not set, want %1 got %2").arg(channels).arg(vval);
            channels = vval;
        }
        qLog(QAudioInput) << "channels = " << vval;

        snd_pcm_hw_params_get_rate(hwparams, &vval, &dir);
        if ( (int)vval != (int)frequency ) {
            qLog(QAudioInput) << QString("frequency type not set, want %1 got %2").arg(frequency).arg(vval);
            frequency = vval;
        }
        qLog(QAudioInput) << "rate =" <<  vval << " bps";

        snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);
        qLog(QAudioInput) << "period time =" << period_time << " us";
        snd_pcm_hw_params_get_period_size(hwparams,&period_size, &dir);
        qLog(QAudioInput) << "period size =" << (int)period_size;
        snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
        qLog(QAudioInput) << "buffer time =" << buffer_time;
        snd_pcm_hw_params_get_buffer_size(hwparams,(snd_pcm_uframes_t *) &buffer_size);
        qLog(QAudioInput) << "buffer size =" << (int)buffer_size;
        snd_pcm_hw_params_get_periods(hwparams, &vval, &dir);
        qLog(QAudioInput) << "periods per buffer =" << vval;
        snd_pcm_hw_params_get_rate_numden(hwparams, &vval, &vval2);
        qLog(QAudioInput) << QString("exact rate = %1/%2 bps").arg(vval).arg(vval2).toLatin1().constData();
        vval = snd_pcm_hw_params_get_sbits(hwparams);
        qLog(QAudioInput) << "significant bits =" << vval;
        snd_pcm_hw_params_get_tick_time(hwparams,&vval, &dir);
        qLog(QAudioInput) << "tick time =" << vval;
        vval = snd_pcm_hw_params_is_batch(hwparams);
        qLog(QAudioInput) << "is batch =" << vval;
        vval = snd_pcm_hw_params_is_block_transfer(hwparams);
        qLog(QAudioInput) << "is block transfer =" << vval;
        vval = snd_pcm_hw_params_is_double(hwparams);
        qLog(QAudioInput) << "is double =" << vval;
        vval = snd_pcm_hw_params_is_half_duplex(hwparams);
        qLog(QAudioInput) << "is half duplex =" << vval;
        vval = snd_pcm_hw_params_is_joint_duplex(hwparams);
        qLog(QAudioInput) << "is joint duplex =" << vval;
        vval = snd_pcm_hw_params_can_overrange(hwparams);
        qLog(QAudioInput) << "can overrange =" << vval;
        vval = snd_pcm_hw_params_can_mmap_sample_resolution(hwparams);
        qLog(QAudioInput) << "can mmap =" << vval;
        vval = snd_pcm_hw_params_can_pause(hwparams);
        qLog(QAudioInput) << "can pause =" << vval;
        vval = snd_pcm_hw_params_can_resume(hwparams);
        qLog(QAudioInput) << "can resume =" << vval;
        vval = snd_pcm_hw_params_can_sync_start(hwparams);
        qLog(QAudioInput) << "can sync start =" << vval;

        snd_pcm_sw_params_t *swparams;
        snd_pcm_sw_params_alloca(&swparams);
        err = snd_pcm_sw_params_current(handle, swparams);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_sw_params_current: err %d",err);
        }
        err = snd_pcm_sw_params_set_start_threshold(handle,swparams,period_size);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_sw_params_set_start_threshold: err %d",err);
        }
        err = snd_pcm_sw_params_set_avail_min(handle, swparams,period_size);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_sw_params_set_avail_min: err %d",err);
        }
        err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_sw_params_set_xfer_align: err %d",err);
        }
        err = snd_pcm_sw_params(handle, swparams);
        if ( err < 0 ) {
            qWarning( "QAudioInput: snd_pcm_sw_params: err %d",err);
        }

        snd_pcm_prepare(handle);
        snd_pcm_start(handle);

        int     count = snd_pcm_poll_descriptors_count(handle);
        pollfd  *pfds = new pollfd[count];

        snd_pcm_poll_descriptors(handle, pfds, count);

        for (int i = 0; i < count; ++i)
        {
            if ((pfds[i].events & POLLIN) != 0) {
                notifier = new QSocketNotifier(pfds[i].fd, QSocketNotifier::Read);
                QObject::connect(notifier,
                                 SIGNAL(activated(int)),
                                 input,
                                 SIGNAL(readyRead()));

                break;
            }
        }

        if (notifier == NULL) {
            rc = false;
        }

        delete pfds;
    }

    return rc;
}
Example #23
0
int initAlsa(char **argv,int optind)
{
    snd_pcm_hw_params_t *hw_params;
    int err,n;
    unsigned int Fs;

    if ((err = snd_pcm_open(&capture_handle, argv[optind],
                            SND_PCM_STREAM_CAPTURE, 0)) < 0) {
        fprintf(stderr, "Alsa cannot open audio device %s (%s)\n",argv[optind], snd_strerror(err));
        return 1;
    }

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

    if ((err = snd_pcm_hw_params_any(capture_handle, hw_params)) < 0) {
        fprintf(stderr,
                "Alsa cannot initialize hardware parameter structure (%s)\n",snd_strerror(err));
        return 1;
    }

    if ((err = snd_pcm_hw_params_set_access(capture_handle, hw_params,SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
        fprintf(stderr, "Alsa cannot set access type (%s)\n",snd_strerror(err));
        return 1;
    }

    if ((err = snd_pcm_hw_params_set_format(capture_handle, hw_params,SND_PCM_FORMAT_S16)) < 0) {
        fprintf(stderr, "Alsa cannot set sample format (%s)\n",snd_strerror(err));
        return 1;
    }

    snd_pcm_hw_params_set_rate_resample(capture_handle, hw_params,0);
    Fs=19200;
    n=1;
    if ((err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &Fs,&n)) < 0) {
        fprintf(stderr, "Alsa cannot set sample rate (%s)\n",snd_strerror(err));
        return 1;
    }
    fprintf(stderr, "Alsa sample rate %d\n",Fs);

    if(snd_pcm_hw_params_get_channels (hw_params, &nbch)!=0) {
        fprintf(stderr, "Alsa cannot get number of channels\n");
        return 1;
    }
    if(nbch>4) {
        fprintf(stderr, "Alsa too much channels\n");
        return 1;

    }
    if ((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0) {
        fprintf(stderr, "Alsa cannot set parameters (%s)\n",snd_strerror(err));
        return 1;
    }
    snd_pcm_hw_params_free(hw_params);

    if ((err = snd_pcm_prepare(capture_handle)) < 0) {
        fprintf(stderr,
                "Alsa cannot prepare audio interface for use (%s)\n",snd_strerror(err));
        return 1;
    }

    for(n=0; n<nbch; n++) {
        channel[n].chn=n;
        channel[n].Infs=Fs;
        channel[n].InBuff=malloc(MAXNBFRAMES*sizeof(sample_t));
    }
    for(; n<MAXNBCHANNELS; n++) channel[n].Infs=0;

    return (0);
}
Example #24
0
pcm_player *pcm_player_init(int framerate, int nchannels, int sampwidth)
{
    pcm_player *player;
    int retval, format, buffsz;
    char *buff, *devname;
    snd_pcm_t *pcm_handle;
    snd_pcm_stream_t stream;
    snd_pcm_hw_params_t *hwparams;
    snd_pcm_uframes_t periodsize;

    // check parameters
    if(nchannels != 1 && nchannels != 2) {
        fprintf(stderr, "error: unsupported channels: %d\n", nchannels);
        return NULL;
    }

    if(sampwidth == 1)
        format = SND_PCM_FORMAT_U8;
    else if(sampwidth == 2)
        format = SND_PCM_FORMAT_S16_LE;
    else if(sampwidth == 3)
        format = SND_PCM_FORMAT_S24_LE;
    else if(sampwidth == 4)
        format = SND_PCM_FORMAT_S32_LE;
    else {
        fprintf(stderr, "error: unsupported sample width: %d\n", sampwidth);
        return NULL;
    }

    // allocate the structure
    player = (pcm_player*)malloc(sizeof(pcm_player));
    if(player == NULL)
        return NULL;


    // open the PCM device in playback mode
    devname = "default";
    stream = SND_PCM_STREAM_PLAYBACK;
    if((retval = snd_pcm_open(&pcm_handle, devname, stream, 0)) < 0) {
        fprintf(stderr, "error: can't PCM device: %s\n", snd_strerror(retval));
        free(player);
        return NULL;
    }

    // allocate parameters object and fill it with default values
    snd_pcm_hw_params_alloca(&hwparams);
    snd_pcm_hw_params_any(pcm_handle, hwparams);

    // set parameters
    if((retval = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
        fprintf(stderr, "error: can't set interleaved mode: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    if ((retval = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format)) < 0) {
        fprintf(stderr, "error: can't set format: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    if ((retval = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, nchannels)) < 0) {
        fprintf(stderr, "error: can't set channels: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    if ((retval = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &framerate, 0)) < 0) {
        fprintf(stderr, "error: can't set rate: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    periodsize = framerate / 10;
    if((retval = snd_pcm_hw_params_set_period_size(pcm_handle, hwparams, periodsize, 0)) < 0) {
        fprintf(stderr, "error: can't set period size: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    // write parameters
    if ((retval = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
        fprintf(stderr, "error: can't set hardware parameters: %s\n", snd_strerror(retval));
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    // resume information
    printf("PCM name: %s\n", snd_pcm_name(pcm_handle));

    snd_pcm_hw_params_get_channels(hwparams, &nchannels);
    printf("channels: %i ", nchannels);
    if (nchannels == 1)
        printf("(mono)\n");
    else if (nchannels == 2)
        printf("(stereo)\n");

    snd_pcm_hw_params_get_rate(hwparams, &framerate, 0);
    printf("framerate: %d Hz\n", framerate);

    // allocate buffer to hold single period
    snd_pcm_hw_params_get_period_size(hwparams, &periodsize, 0);
    printf("period size: %d\n", periodsize);

    buffsz = sampwidth * nchannels * periodsize;
    printf("buffer size: %d\n", buffsz);

    buff = (char*)malloc(buffsz);
    if(buff == NULL) {
        fprintf(stderr, "error: can't allocate pcm buffer\n");
        snd_pcm_close(pcm_handle);
        free(player);
        return NULL;
    }

    // set player attributes
    player->pcm_handle = pcm_handle;
    player->framerate = framerate;
    player->nchannels = nchannels;
    player->sampwidth = sampwidth;
    player->periodsize = periodsize;
    player->buffersize = buffsz;
    player->buffer = buff;

    return player;
}
Example #25
0
    bool open()
    {
        // Open the Alsa playback device.
        int err=-1,count=0;
        unsigned int        freakuency = frequency;

        while((count < 5) && (err < 0)) {
            err = snd_pcm_open
                  ( &handle,  ALSA_OUTPUT_NAME, SND_PCM_STREAM_PLAYBACK, 0 );

            if(err < 0) {
                count++;
                qWarning()<<"QAudioOutput::open() err="<<err<<", count="<<count;
            }
        }
        if (( err < 0)||(handle == 0)) {
            qWarning( "QAudioOuput: snd_pcm_open: error %d", err );
            return false;
        }
        snd_pcm_nonblock( handle, 0 );

        // Set the desired HW parameters.
        snd_pcm_hw_params_t *hwparams;
        snd_pcm_hw_params_alloca( &hwparams );

        err = snd_pcm_hw_params_any( handle, hwparams );
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_any: err %d", err);
            return false;
        }

        err = snd_pcm_hw_params_set_access( handle, hwparams, access );
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_set_access: err %d", err);
            return false;
        }

        err = snd_pcm_hw_params_set_format( handle, hwparams,
             ( bitsPerSample == 16 ? SND_PCM_FORMAT_S16
                                   : SND_PCM_FORMAT_U8 ) );
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_set_format: err %d", err);
            return false;
        }

        err = snd_pcm_hw_params_set_channels
            ( handle, hwparams, (unsigned int)channels );
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_set_channels: err %d", err);
            return false;
        }

        err = snd_pcm_hw_params_set_rate_near
            ( handle, hwparams, &freakuency, 0 );
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_set_rate_near: err %d", err);
            return false;
        }

#ifndef ALSA_BUFFER_SIZE
        err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err %d",err);
        }
        err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_get_buffer_size: err %d",err);
        }
#else
        buffer_size = ALSA_BUFFER_SIZE;
        err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err %d",err);
        }
#endif

#ifndef ALSA_PERIOD_SIZE
        period_time = buffer_time/4;
        err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, 0);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_set_period_time_near: err %d",err);
        }
#else
        period_size = ALSA_PERIOD_SIZE;
        err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, 0);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params_set_period_size_near: err %d",err);
        }
#endif

        err = snd_pcm_hw_params(handle, hwparams);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_hw_params: err %d", err);
            return false;
        }

        int                  dir;
        unsigned int         vval, vval2;
        snd_pcm_access_t     val;
        snd_pcm_format_t     fval;
        snd_pcm_subformat_t  sval;


        qLog(QAudioOutput) << "PCM handle name =" << snd_pcm_name(handle);
        qLog(QAudioOutput) << "PCM state =" << snd_pcm_state_name(snd_pcm_state(handle));
        snd_pcm_hw_params_get_access(hwparams,&val);
        vval = (unsigned int)val;
        if ( (int)vval != (int)access ) {
            qWarning( "QAudioInput: access type not set, want %s got %s",
                    snd_pcm_access_name((snd_pcm_access_t)access),
                    snd_pcm_access_name((snd_pcm_access_t)vval) );
            access = (snd_pcm_access_t)vval;
        }
        qLog(QAudioOutput) << "access type =" << snd_pcm_access_name((snd_pcm_access_t)vval);
        snd_pcm_hw_params_get_format(hwparams, &fval);
        vval = (unsigned int)fval;
        if ( (int)vval != (int)format ) {
            qWarning( "QAudioInput: format type not set, want %s got %s",
                    snd_pcm_format_name((snd_pcm_format_t)format),
                    snd_pcm_format_name((snd_pcm_format_t)vval) );
            format = (snd_pcm_format_t)vval;
        }
        qLog(QAudioOutput) << QString("format = '%1' (%2)").arg(snd_pcm_format_name((snd_pcm_format_t)vval))
            .arg(snd_pcm_format_description((snd_pcm_format_t)vval))
            .toLatin1().constData();
        snd_pcm_hw_params_get_subformat(hwparams,&sval);
        vval = (unsigned int)sval;
        qLog(QAudioOutput) << QString("subformat = '%1' (%2)").arg(snd_pcm_subformat_name((snd_pcm_subformat_t)vval))
            .arg(snd_pcm_subformat_description((snd_pcm_subformat_t)vval))
            .toLatin1().constData();
        snd_pcm_hw_params_get_channels(hwparams, &vval);
        if ( (int)vval != (int)channels ) {
            qWarning( "QAudioInput: channels type not set, want %d got %d",channels,vval);
            channels = vval;
        }
        qLog(QAudioOutput) << "channels =" << vval;
        snd_pcm_hw_params_get_rate(hwparams, &vval, &dir);
        if ( (int)vval != (int)frequency ) {
            qWarning( "QAudioInput: frequency type not set, want %d got %d",frequency,vval);
            frequency = vval;
        }
        qLog(QAudioOutput) << "rate =" << vval << "bps";
        snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);
        qLog(QAudioOutput) << "period time =" << period_time << "us";
        snd_pcm_hw_params_get_period_size(hwparams,&period_size, &dir);
        qLog(QAudioOutput) << "period size =" << (int)period_size << "frames";
        qLog(QAudioOutput) << "buffer time =" << (int)buffer_time << "us";
        qLog(QAudioOutput) << "buffer size =" << (int)buffer_size << "frames";
        snd_pcm_hw_params_get_periods(hwparams, &vval, &dir);
        periods = vval;
        qLog(QAudioOutput) << "periods per buffer =" << vval << "frames";
        snd_pcm_hw_params_get_rate_numden(hwparams, &vval, &vval2);
        qLog(QAudioOutput) << QString("exact rate = %1/%2 bps").arg(vval).arg(vval2).toLatin1().constData();
        vval = snd_pcm_hw_params_get_sbits(hwparams);
        qLog(QAudioOutput) << "significant bits =" << vval;
        vval = snd_pcm_hw_params_is_batch(hwparams);
        qLog(QAudioOutput) << "is batch =" << vval;
        vval = snd_pcm_hw_params_is_block_transfer(hwparams);
        qLog(QAudioOutput) << "is block transfer =" << vval;
        vval = snd_pcm_hw_params_is_double(hwparams);
        qLog(QAudioOutput) << "is double =" << vval;
        vval = snd_pcm_hw_params_is_half_duplex(hwparams);
        qLog(QAudioOutput) << "is half duplex =" << vval;
        vval = snd_pcm_hw_params_is_joint_duplex(hwparams);
        qLog(QAudioOutput) << "is joint duplex =" << vval;
        vval = snd_pcm_hw_params_can_overrange(hwparams);
        qLog(QAudioOutput) << "can overrange =" << vval;
        vval = snd_pcm_hw_params_can_mmap_sample_resolution(hwparams);
        qLog(QAudioOutput) << "can mmap =" << vval;
        vval = snd_pcm_hw_params_can_pause(hwparams);
        qLog(QAudioOutput) << "can pause =" << vval;
        vval = snd_pcm_hw_params_can_resume(hwparams);
        qLog(QAudioOutput) << "can resume =" << vval;
        vval = snd_pcm_hw_params_can_sync_start(hwparams);
        qLog(QAudioOutput) << "can sync start =" << vval;

        // Set the desired SW parameters.
        snd_pcm_sw_params_t *swparams;
        snd_pcm_sw_params_alloca(&swparams);
        err = snd_pcm_sw_params_current(handle, swparams);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_sw_params_current: err %d",err);
        }
        err = snd_pcm_sw_params_set_start_threshold(handle,swparams,buffer_size);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_sw_params_set_start_threshold: err %d",err);
        }
        err = snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_size);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_sw_params_set_stop_threshold: err %d",err);
        }
        err = snd_pcm_sw_params_set_avail_min(handle, swparams,period_size);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_sw_params_set_avail_min: err %d",err);
        }
        err = snd_pcm_sw_params(handle, swparams);
        if ( err < 0 ) {
            qWarning( "QAudioOutput: snd_pcm_sw_params: err %d",err);
        }

        // Prepare for audio output.
        snd_pcm_prepare( handle );

        return true;
    }
Example #26
0
static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	int                  status;
	snd_pcm_hw_params_t *params;
	snd_pcm_format_t     format;
	snd_pcm_uframes_t    frames;
	Uint16               test_format;

	/* Open the audio device */
	status = snd_pcm_open(&pcm_handle, get_audio_device(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
	if ( status < 0 ) {
		SDL_SetError("Couldn't open audio device: %s", snd_strerror(status));
		return(-1);
	}

	/* Figure out what the hardware is capable of */
	snd_pcm_hw_params_alloca(&params);
	status = snd_pcm_hw_params_any(pcm_handle, params);
	if ( status < 0 ) {
		SDL_SetError("Couldn't get hardware config: %s", snd_strerror(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

	/* SDL only uses interleaved sample output */
	status = snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set interleaved access: %s", snd_strerror(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

	/* Try for a closest match on audio format */
	status = -1;
	for ( test_format = SDL_FirstAudioFormat(spec->format);
	      test_format && (status < 0); ) {
		switch ( test_format ) {
			case AUDIO_U8:
				format = SND_PCM_FORMAT_U8;
				break;
			case AUDIO_S8:
				format = SND_PCM_FORMAT_S8;
				break;
			case AUDIO_S16LSB:
				format = SND_PCM_FORMAT_S16_LE;
				break;
			case AUDIO_S16MSB:
				format = SND_PCM_FORMAT_S16_BE;
				break;
			case AUDIO_U16LSB:
				format = SND_PCM_FORMAT_U16_LE;
				break;
			case AUDIO_U16MSB:
				format = SND_PCM_FORMAT_U16_BE;
				break;
			default:
				format = 0;
				break;
		}
		if ( format != 0 ) {
			status = snd_pcm_hw_params_set_format(pcm_handle, params, format);
		}
		if ( status < 0 ) {
			test_format = SDL_NextAudioFormat();
		}
	}
	if ( status < 0 ) {
		SDL_SetError("Couldn't find any hardware audio formats");
		ALSA_CloseAudio(this);
		return(-1);
	}
	spec->format = test_format;

	/* Set the number of channels */
	status = snd_pcm_hw_params_set_channels(pcm_handle, params, spec->channels);
	if ( status < 0 ) {
		status = snd_pcm_hw_params_get_channels(params);
		if ( (status <= 0) || (status > 2) ) {
			SDL_SetError("Couldn't set audio channels");
			ALSA_CloseAudio(this);
			return(-1);
		}
		spec->channels = status;
	}

	/* Set the audio rate */
	status = snd_pcm_hw_params_set_rate_near(pcm_handle, params, spec->freq, NULL);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set audio frequency: %s", snd_strerror(status));
		ALSA_CloseAudio(this);
		return(-1);
	}
	spec->freq = status;

	/* Set the buffer size, in samples */
	frames = spec->samples;
	frames = snd_pcm_hw_params_set_period_size_near(pcm_handle, params, frames, NULL);
	spec->samples = frames;
	snd_pcm_hw_params_set_periods_near(pcm_handle, params, 2, NULL);

	/* "set" the hardware with the desired parameters */
	status = snd_pcm_hw_params(pcm_handle, params);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set audio parameters: %s", snd_strerror(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

	/* Calculate the final parameters for this audio specification */
	SDL_CalculateAudioSpec(spec);

	/* Allocate mixing buffer */
	mixlen = spec->size;
	mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen);
	if ( mixbuf == NULL ) {
		ALSA_CloseAudio(this);
		return(-1);
	}
	memset(mixbuf, spec->silence, spec->size);

	/* Get the parent process id (we're the parent of the audio thread) */
	parent = getpid();

	/* Switch to blocking mode for playback */
	snd_pcm_nonblock(pcm_handle, 0);

	/* We're ready to rock and roll. :-) */
	return(0);
}
Example #27
0
int record(int size,char *serverString)
{
	unsigned int pcm, tmp, dir;
	int rate, channels, seconds;
	snd_pcm_t *pcm_handle;
	snd_pcm_hw_params_t *params;
	snd_pcm_uframes_t frames;
	char *buff,*buf;
	int buff_size, loops;
	int fp; 
	/*if (argc < 4)
	{
		printf("Usage: %s <sample_rate> <channels> <seconds>\n",
				argv[0]);
		return -1;
	}*/

	rate = 8000;//atoi(argv[1]);
	channels = 1;//atoi(argv[2]);
	seconds = 10;//atoi(argv[3]);

	/* Open the PCM device in playback mode */
	if (pcm = snd_pcm_open(&pcm_handle, "default" ,	SND_PCM_STREAM_PLAYBACK, 0) < 0)
		printf("ERROR: Can't open \"%s\" PCM device. %s\n",	"default", snd_strerror(pcm));

	/* Allocate parameters object and fill it with default values*/
	snd_pcm_hw_params_alloca(&params);

	snd_pcm_hw_params_any(pcm_handle, params);

	/* Set parameters */
	if (pcm = snd_pcm_hw_params_set_access(pcm_handle, params,SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
		printf("ERROR: Can't set interleaved mode. %s\n", snd_strerror(pcm));

	if (pcm = snd_pcm_hw_params_set_format(pcm_handle, params,SND_PCM_FORMAT_U8) < 0)
		printf("ERROR: Can't set format. %s\n", snd_strerror(pcm));

	if (pcm = snd_pcm_hw_params_set_channels(pcm_handle, params, channels) < 0)
		printf("ERROR: Can't set channels number. %s\n", snd_strerror(pcm));

	if (pcm = snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, 0) < 0)
		printf("ERROR: Can't set rate. %s\n", snd_strerror(pcm));

	/* Write parameters */
	if (pcm = snd_pcm_hw_params(pcm_handle, params) < 0)
		printf("ERROR: Can't set harware parameters. %s\n", snd_strerror(pcm));

	/* Resume information */
	printf("PCM name: '%s'\n", snd_pcm_name(pcm_handle));

	printf("PCM state: %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle)));

	snd_pcm_hw_params_get_channels(params, &tmp);
	printf("channels: %i ", tmp);

	if (tmp == 1)
		printf("(mono)\n");
	else if (tmp == 2)
		printf("(stereo)\n");

	snd_pcm_hw_params_get_rate(params, &tmp, 0);
	printf("rate: %d bps\n", tmp);

	printf("seconds: %d\n", seconds);	

	/* Allocate buffer to hold single period */
	snd_pcm_hw_params_get_period_size(params, &frames, 0);

	buff_size = frames * channels * 2 /* 2 -> sample size */;
	buff = (char *) malloc(buff_size*3);

	size = frames * channels * 2 /* 2 -> sample size */;
	buf = (char *) realloc((void*)serverString,(size*3));
	
	snd_pcm_hw_params_get_period_time(params, &tmp, NULL);
	
	//fp=open("222.wav",O_RDONLY);
	for (loops = (seconds * 1000000) / tmp; loops > 0; loops--)
	{

		/*
		if (pcm = read(fp, buff, buff_size) == 0)
		{
			printf("Early end of file.\n");
			//return 0;
		}
		*/
		
		if (pcm = snd_pcm_writei(pcm_handle, buf, frames) == -EPIPE)
		{
			printf("XRUN.\n");

			snd_pcm_prepare(pcm_handle);
		} 
		else 
		if(pcm < 0) 
		{
			printf("ERROR. Can't write to PCM device. %s\n", snd_strerror(pcm));
		}
		
	}

	snd_pcm_drain(pcm_handle);
	snd_pcm_close(pcm_handle);
	free(buff);

	return 0;
}
int main(int argc, char ** argv) {
    
    // Variable declaration
	int rc;
	char * buffer;
  	int buffer_size;
  	int periods_per_buffer;

  	snd_pcm_t *handle;
  	snd_pcm_hw_params_t *params;
  	snd_pcm_uframes_t frames;

  	unsigned int channels;
  	unsigned int rate;

	wav_header * wav_header_info;

  	FILE * fp;

    
    // Argument parsing
  	if (argc != 2)
	{
        printf("Incorrect usage: Enter filename of the wav file you want to play as an argument: %s filename.txt\n", argv[0]);
		return 1;
	}

    
    // Open wav file to read
	fp = fopen(argv[1], "rb");

	if (fp == NULL)
	{
		printf("ERROR: %s does not exist, or cannot be opened.\n", argv[1]);
		return 1;
	}

	wav_header_info = malloc(44);

	fread(wav_header_info, 1, 44, fp);
    

	// print_wav_header(wav_header_info);

    
    // Assign variables that were read from the wave file
	channels = wav_header_info->number_of_channels;
	rate = wav_header_info->sample_rate;
	periods_per_buffer = 2; // Down to user preference, depending on size of internal ring buffer of ALSA


  	// Open PCM device for playback
  	if ((rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) 
  	{
    	printf("ERROR: Cannot open pcm device. %s\n", snd_strerror(rc));
  	}

    
  	// Allocate hardware parameters
  	if ((rc = snd_pcm_hw_params_malloc(&params)) < 0)
  	{
  		printf("ERROR: Cannot allocate hardware parameters. %s\n", snd_strerror(rc));
  	}

    
  	// Initialize parameters with default values
  	if ((rc = snd_pcm_hw_params_any(handle, params)) < 0)
  	{
  		printf("ERROR: Cannot initialize hardware parameters. %s\n", snd_strerror(rc));
  	}


  	// Setting hardware parameters
  	if ((rc = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
  	{
  		printf("ERROR: Cannot set interleaved mode. %s\n", snd_strerror(rc));
  	}

  	if ((rc = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE)) < 0)
  	{
  		printf("ERROR: Cannot set PCM format. %s\n", snd_strerror(rc));
  	}

  	if ((rc = snd_pcm_hw_params_set_channels_near(handle, params, &channels)) < 0)
  	{
  		printf("ERROR: Cannot set number of channels. %s\n", snd_strerror(rc));
  	}

 	if ((rc = snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0)) < 0)
 	{
 		printf("ERROR: Cannot set plyabck rate. %s\n", snd_strerror(rc));
 	}

 	if ((rc = snd_pcm_hw_params(handle, params)) < 0)
 	{
 		printf("ERROR: Cannot set hardware parameters. %s\n", snd_strerror(rc));
 	}


 	// Get hardware parameters
 	if ((rc = snd_pcm_hw_params_get_period_size(params, &frames, 0)) < 0)
	{
		printf("Playback ERROR: Can't get period size. %s\n", snd_strerror(rc));
	}
	printf("Frames: %lu\n", frames);

	if ((rc = snd_pcm_hw_params_get_channels(params, &channels)) < 0)
	{
		printf("Playback ERROR: Can't get channel number. %s\n", snd_strerror(rc));
	}

	if ((rc = snd_pcm_hw_params_get_rate(params, &rate, 0)) < 0)
	{
		printf("ERROR: Cannot get rate. %s\n", snd_strerror(rc));
	}


	// Free paraemeters
	snd_pcm_hw_params_free(params);


	// Create buffer
  	buffer_size = frames * periods_per_buffer * channels * sizeof(int16_t); /* 2 bytes/sample, 2 channels */
  	buffer = (char *) malloc(buffer_size);

  	// Send info to ALSA
 	//while ((rc = read(0, buffer, buffer_size)) != 0) 
 	while (rc = fread(buffer, 1, periods_per_buffer * frames * channels * sizeof(int16_t), fp) != 0)
 	{
    	rc = snd_pcm_writei(handle, buffer, frames * periods_per_buffer);
    	if (rc == -EPIPE) 
    	{
      		fprintf(stderr, "underrun occurred\n");
      		snd_pcm_prepare(handle);
    	} 
    	else if (rc < 0) 
    	{
      		printf("ERROR: Cannot write to playback device. %s\n", strerror(rc));
    	}
  	}

  	printf("Info set: Device is now draining...\n");
  	snd_pcm_drain(handle);

  	printf("Done playing, closing connections.\n");
  	snd_pcm_close(handle);

  	free(wav_header_info);
  	free(buffer);
  	fclose(fp);

  return 0;
}
Example #29
0
int ai_alsa_setup(audio_in_t *ai)
{
    snd_pcm_hw_params_t *params;
    snd_pcm_sw_params_t *swparams;
    snd_pcm_uframes_t buffer_size, period_size;
    int err;
    int dir;
    unsigned int rate;

    snd_pcm_hw_params_alloca(&params);
    snd_pcm_sw_params_alloca(&swparams);

    err = snd_pcm_hw_params_any(ai->alsa.handle, params);
    if (err < 0) {
	mp_tmsg(MSGT_TV, MSGL_ERR, "Broken configuration for this PCM: no configurations available.\n");
	return -1;
    }

    err = snd_pcm_hw_params_set_access(ai->alsa.handle, params,
				       SND_PCM_ACCESS_RW_INTERLEAVED);
    if (err < 0) {
	mp_tmsg(MSGT_TV, MSGL_ERR, "Access type not available.\n");
	return -1;
    }

    err = snd_pcm_hw_params_set_format(ai->alsa.handle, params, SND_PCM_FORMAT_S16_LE);
    if (err < 0) {
	mp_tmsg(MSGT_TV, MSGL_ERR, "Sample format not available.\n");
	return -1;
    }

    err = snd_pcm_hw_params_set_channels(ai->alsa.handle, params, ai->req_channels);
    if (err < 0) {
	snd_pcm_hw_params_get_channels(params, &ai->channels);
	mp_tmsg(MSGT_TV, MSGL_ERR, "Channel count not available - reverting to default: %d\n",
	       ai->channels);
    } else {
	ai->channels = ai->req_channels;
    }

    dir = 0;
    rate = ai->req_samplerate;
    err = snd_pcm_hw_params_set_rate_near(ai->alsa.handle, params, &rate, &dir);
    if (err < 0) {
	mp_tmsg(MSGT_TV, MSGL_ERR, "Cannot set samplerate.\n");
    }
    ai->samplerate = rate;

    dir = 0;
    ai->alsa.buffer_time = 1000000;
    err = snd_pcm_hw_params_set_buffer_time_near(ai->alsa.handle, params,
						 &ai->alsa.buffer_time, &dir);
    if (err < 0) {
	mp_tmsg(MSGT_TV, MSGL_ERR, "Cannot set buffer time.\n");
    }

    dir = 0;
    ai->alsa.period_time = ai->alsa.buffer_time / 4;
    err = snd_pcm_hw_params_set_period_time_near(ai->alsa.handle, params,
						 &ai->alsa.period_time, &dir);
    if (err < 0) {
	mp_tmsg(MSGT_TV, MSGL_ERR, "Cannot set period time.\n");
    }

    err = snd_pcm_hw_params(ai->alsa.handle, params);
    if (err < 0) {
	mp_tmsg(MSGT_TV, MSGL_ERR, "Unable to install hardware parameters: %s", snd_strerror(err));
	snd_pcm_hw_params_dump(params, ai->alsa.log);
	return -1;
    }

    dir = -1;
    snd_pcm_hw_params_get_period_size(params, &period_size, &dir);
    snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
    ai->alsa.chunk_size = period_size;
    if (period_size == buffer_size) {
	mp_tmsg(MSGT_TV, MSGL_ERR, "Can't use period equal to buffer size (%u == %lu)\n", ai->alsa.chunk_size, (long)buffer_size);
	return -1;
    }

    snd_pcm_sw_params_current(ai->alsa.handle, swparams);
    err = snd_pcm_sw_params_set_avail_min(ai->alsa.handle, swparams, ai->alsa.chunk_size);

    err = snd_pcm_sw_params_set_start_threshold(ai->alsa.handle, swparams, 0);
    err = snd_pcm_sw_params_set_stop_threshold(ai->alsa.handle, swparams, buffer_size);

    if (snd_pcm_sw_params(ai->alsa.handle, swparams) < 0) {
	mp_tmsg(MSGT_TV, MSGL_ERR, "Unable to install software parameters:\n");
	snd_pcm_sw_params_dump(swparams, ai->alsa.log);
	return -1;
    }

    if (mp_msg_test(MSGT_TV, MSGL_V)) {
	snd_pcm_dump(ai->alsa.handle, ai->alsa.log);
    }

    ai->alsa.bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE);
    ai->alsa.bits_per_frame = ai->alsa.bits_per_sample * ai->channels;
    ai->blocksize = ai->alsa.chunk_size * ai->alsa.bits_per_frame / 8;
    ai->samplesize = ai->alsa.bits_per_sample;
    ai->bytes_per_sample = ai->alsa.bits_per_sample/8;

    return 0;
}
Example #30
0
int ai_alsa_setup(audio_in_t *ai)
{
    snd_pcm_hw_params_t *params;
    snd_pcm_sw_params_t *swparams;
    int buffer_size;
    int err;
    unsigned int rate;

    snd_pcm_hw_params_alloca(&params);
    snd_pcm_sw_params_alloca(&swparams);

    err = snd_pcm_hw_params_any(ai->alsa.handle, params);
    if (err < 0) {
	mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AIALSA_PcmBrokenConfig);
	return -1;
    }
    err = snd_pcm_hw_params_set_access(ai->alsa.handle, params,
				       SND_PCM_ACCESS_RW_INTERLEAVED);
    if (err < 0) {
	mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AIALSA_UnavailableAccessType);
	return -1;
    }
    err = snd_pcm_hw_params_set_format(ai->alsa.handle, params, SND_PCM_FORMAT_S16_LE);
    if (err < 0) {
	mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AIALSA_UnavailableSampleFmt);
	return -1;
    }
    err = snd_pcm_hw_params_set_channels(ai->alsa.handle, params, ai->req_channels);
    if (err < 0) {
	ai->channels = snd_pcm_hw_params_get_channels(params);
	mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AIALSA_UnavailableChanCount,
	       ai->channels);
    } else {
	ai->channels = ai->req_channels;
    }

    err = snd_pcm_hw_params_set_rate_near(ai->alsa.handle, params, ai->req_samplerate, 0);
    assert(err >= 0);
    rate = err;
    ai->samplerate = rate;

    ai->alsa.buffer_time = 1000000;
    ai->alsa.buffer_time = snd_pcm_hw_params_set_buffer_time_near(ai->alsa.handle, params,
							       ai->alsa.buffer_time, 0);
    assert(ai->alsa.buffer_time >= 0);
    ai->alsa.period_time = ai->alsa.buffer_time / 4;
    ai->alsa.period_time = snd_pcm_hw_params_set_period_time_near(ai->alsa.handle, params,
							       ai->alsa.period_time, 0);
    assert(ai->alsa.period_time >= 0);
    err = snd_pcm_hw_params(ai->alsa.handle, params);
    if (err < 0) {
	mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AIALSA_CannotInstallHWParams);
	snd_pcm_hw_params_dump(params, ai->alsa.log);
	return -1;
    }
    ai->alsa.chunk_size = snd_pcm_hw_params_get_period_size(params, 0);
    buffer_size = snd_pcm_hw_params_get_buffer_size(params);
    if (ai->alsa.chunk_size == buffer_size) {
	mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AIALSA_PeriodEqualsBufferSize, ai->alsa.chunk_size, (long)buffer_size);
	return -1;
    }
    snd_pcm_sw_params_current(ai->alsa.handle, swparams);
    err = snd_pcm_sw_params_set_sleep_min(ai->alsa.handle, swparams,0);
    assert(err >= 0);
    err = snd_pcm_sw_params_set_avail_min(ai->alsa.handle, swparams, ai->alsa.chunk_size);
    assert(err >= 0);

    err = snd_pcm_sw_params_set_start_threshold(ai->alsa.handle, swparams, 0);
    assert(err >= 0);
    err = snd_pcm_sw_params_set_stop_threshold(ai->alsa.handle, swparams, buffer_size);
    assert(err >= 0);

    assert(err >= 0);
    if (snd_pcm_sw_params(ai->alsa.handle, swparams) < 0) {
	mp_msg(MSGT_TV, MSGL_ERR, MSGTR_MPDEMUX_AIALSA_CannotInstallSWParams);
	snd_pcm_sw_params_dump(swparams, ai->alsa.log);
	return -1;
    }

    if (mp_msg_test(MSGT_TV, MSGL_V)) {
	snd_pcm_dump(ai->alsa.handle, ai->alsa.log);
    }

    ai->alsa.bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE);
    ai->alsa.bits_per_frame = ai->alsa.bits_per_sample * ai->channels;
    ai->blocksize = ai->alsa.chunk_size * ai->alsa.bits_per_frame / 8;
    ai->samplesize = ai->alsa.bits_per_sample;
    ai->bytes_per_sample = ai->alsa.bits_per_sample/8;

    return 0;
}