Esempio n. 1
0
static void alsa_log(snd_pcm_hw_params_t* hw_params, snd_pcm_sw_params_t* sw_params)
{
	unsigned period_time;
	snd_pcm_uframes_t period_size;
	unsigned period_count;
	unsigned buffer_time;
	snd_pcm_uframes_t buffer_size;
	unsigned tick_time;

	snd_pcm_uframes_t xfer_align;

	snd_pcm_hw_params_get_period_time(hw_params, &period_time, 0);
	snd_pcm_hw_params_get_period_size(hw_params, &period_size, 0);
	snd_pcm_hw_params_get_periods(hw_params, &period_count, 0);
	snd_pcm_hw_params_get_buffer_time(hw_params, &buffer_time, 0);
	snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
	snd_pcm_hw_params_get_tick_time(hw_params, &tick_time, 0);

	log_std(("sound:alsa: hw period_time %g [us], period_size %d, periods %d, buffer_time %g [us], buffer_size %d, tick_time %g [us]\n",
		(double)(period_time / 1000000.0), (unsigned)period_size, (unsigned)period_count, (double)(buffer_time / 1000000.0), (unsigned)buffer_size, (double)(tick_time / 1000000.0)
	));

	snd_pcm_sw_params_get_xfer_align(sw_params, &xfer_align);
	log_std(("sound:alsa: sw xfer_align %d\n",
		(unsigned)xfer_align
	));
}
Esempio n. 2
0
bool QAlsaAudioInput::open()
{
#ifdef DEBUG_AUDIO
    QTime now(QTime::currentTime());
    qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
#endif
    clockStamp.restart();
    timeStamp.restart();
    elapsedTimeOffset = 0;

    int dir;
    int err = 0;
    int count=0;
    unsigned int sampleRate=settings.sampleRate();

    if (!settings.isValid()) {
        qWarning("QAudioInput: open error, invalid format.");
    } else if (settings.sampleRate() <= 0) {
        qWarning("QAudioInput: open error, invalid sample rate (%d).",
                 settings.sampleRate());
    } else {
        err = -1;
    }

    if (err == 0) {
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        emit errorChanged(errorState);
        return false;
    }


    QString dev = QString(QLatin1String(m_device.constData()));
    QList<QByteArray> devices = QAlsaAudioDeviceInfo::availableDevices(QAudio::AudioInput);
    if(dev.compare(QLatin1String("default")) == 0) {
#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
        if (devices.size() > 0)
            dev = QLatin1String(devices.first());
        else
            return false;
#else
        dev = QLatin1String("hw:0,0");
#endif
    } else {
#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
        dev = QLatin1String(m_device);
#else
        int idx = 0;
        char *name;

        QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData());

        while(snd_card_get_name(idx,&name) == 0) {
            if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0)
                break;
            idx++;
        }
        dev = QString(QLatin1String("hw:%1,0")).arg(idx);
#endif
    }

    // Step 1: try and open the device
    while((count < 5) && (err < 0)) {
        err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
        if(err < 0)
            count++;
    }
    if (( err < 0)||(handle == 0)) {
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        emit stateChanged(deviceState);
        return false;
    }
    snd_pcm_nonblock( handle, 0 );

    // Step 2: Set the desired HW parameters.
    snd_pcm_hw_params_alloca( &hwparams );

    bool fatal = false;
    QString errMessage;
    unsigned int chunks = 8;

    err = snd_pcm_hw_params_any( handle, hwparams );
    if ( err < 0 ) {
        fatal = true;
        errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_any: err = %1").arg(err);
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_access( handle, hwparams, access );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_access: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = setFormat();
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_format: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channelCount() );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_channels: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &sampleRate, 0 );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params(handle, hwparams);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params: err = %1").arg(err);
        }
    }
    if( err < 0) {
        qWarning()<<errMessage;
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        emit stateChanged(deviceState);
        return false;
    }
    snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
    buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
    snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir);
    period_size = snd_pcm_frames_to_bytes(handle,period_frames);
    snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
    snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);

    // Step 3: Set the desired SW parameters.
    snd_pcm_sw_params_t *swparams;
    snd_pcm_sw_params_alloca(&swparams);
    snd_pcm_sw_params_current(handle, swparams);
    snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames);
    snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames);
    snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames);
    snd_pcm_sw_params(handle, swparams);

    // Step 4: Prepare audio
    ringBuffer.resize(buffer_size);
    snd_pcm_prepare( handle );
    snd_pcm_start(handle);

    // Step 5: Setup timer
    bytesAvailable = checkBytesReady();

    if(pullMode)
        connect(audioSource,SIGNAL(readyRead()),this,SLOT(userFeed()));

    // Step 6: Start audio processing
    chunks = buffer_size/period_size;
    timer->start(period_time*chunks/2000);

    errorState  = QAudio::NoError;

    totalTimeValue = 0;

    return true;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
0
int main()
{

const snd_pcm_channel_area_t *areas;
int size;
unsigned char *buffer;
char *pcm_name;
unsigned int rate = 8000;
int chan;
int rc;
unsigned int  val;
char check;
int pcmreturn;

//Set PCM stream and handle
snd_pcm_t *pcm_handle;
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;

//Set HARDWARE parameters
snd_pcm_hw_params_t *hwparams;


//pcm_name = (char *)malloc(10);
pcm_name = "plughw:0,0";


//allocate memory for hardware
if(snd_pcm_hw_params_malloc(&hwparams)<0)
	{

		fprintf(stderr,"No memory allocated for hardware");
		return(-1);
	
	}



if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0) {
      fprintf(stderr, "Error opening PCM device %s\n", pcm_name);
            return(-1);
	        }

//INITIALIZE HARDWARE WITH CONFIGURATION OF THE SOUNDCARD
	if(snd_pcm_hw_params_any(pcm_handle,hwparams)<0)
		{
			fprintf(stderr,"The hardware device cannot be configured\n");


		}




//SET FORMAT TO 16 BIT LITTLE ENDIAN
snd_pcm_hw_params_set_format(pcm_handle,hwparams,SND_PCM_FORMAT_S16_LE);


/* Two channels (stereo) */
 snd_pcm_hw_params_set_channels(pcm_handle,hwparams,2);

 
    /* 44100 bits/second sampling rate (CD quality) */
      
 if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) {
       fprintf(stderr, "Error setting access.\n");
             return(-1);
	         }


//SETTING RATE ie SAMPLING FREQUENCY

snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0);


//SETTING HARDWARE PARAMETERS

	if(rc=(snd_pcm_hw_params(pcm_handle,hwparams))<0)
		{
			fprintf(stderr,"\nCannot set hardware parameters\n");
			return -1;
		}



//snd_pcm_uframes_t periodsize = 8192;


snd_pcm_uframes_t  frames,offset ;//OF TYPE UNSIGNED LONG
snd_pcm_sframes_t commitres;
//frames =32;


//SETTING SOME MORE PARAMETERS

//size = frames*4;
//SETTING BUFFER SIZE

/*if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize*2)>>2) < 0) {
      fprintf(stderr, "Error setting buffersize.\n");
            return(-1);


}
*/

int first=0;;
int err;
snd_pcm_sframes_t avail = snd_pcm_avail_update(pcm_handle);
printf("\nNumber of frames available is : %d \n",(int)avail);


//-------------------------------------------------------------------------------------------------------
//<<<<<<<<<<<<<<<<<<<<<<DISPLAYING INFORMATION>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//Buffer size

snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t*)&val);
printf("\nThe buffer size is %d \n",val);


//Buffer time

snd_pcm_hw_params_get_buffer_time(hwparams, &val,0);
printf("\nBuffer time is : %d \n",val);


//Period size

snd_pcm_hw_params_get_period_size(hwparams,&frames,0);
printf("\nperiod size : %d \n",(int)frames);



////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
//<<<<<<<<<<<<<mmap_begin>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


err=snd_pcm_mmap_begin(pcm_handle,&areas,&offset,&frames);


//Periods between buffer

snd_pcm_hw_params_get_periods(hwparams,&val,0);
printf("\n Periods between buffer is : %d \n",val);




//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.

if(err<0)
	{
	printf("\nMMAP error\n");
	return -1;

	
	
	}
else printf("\n%d\n",err);


/*
commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames);
if(commitres<0)
	{
		printf("\nFrames not committed to memory\n");
	}

*/

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<               >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,OPENING FILE>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>....



int dest =  open("sample3.wav",O_RDONLY);

if(dest<0)
	{
		perror("\nFile could not be opened\n");
		return -1;
	}



//buffer = (unsigned char *)malloc(1000);

/*

unsigned long buf = offset;
 if(read(dest,&offset,1)<0)
	{
		perror("\nNo destination for read\n");
		return -1;
	}
*/


/*
avail=snd_pcm_avail_update(pcm_handle);
printf("\nAvailable frames = %d \n\n",(int)avail);
struct timeval tvbefore,tvafter;
gettimeofday(&tvbefore,NULL);
*/
unsigned char *ptr[2];



int i;
//unsigned int steps=0;

for(i=0;i<2;i++)
 ptr[i] = (unsigned char*)areas[i].addr  + (areas[i].first/8) + offset*(areas[i].step/8);

printf("\nOffset of the first sample : %u \n",areas[0].first);
printf("\n\nOffset of the memory map is : %u \n",areas[0].step/8);
printf("\nAreas start address is : %u \n",areas[0].addr);
printf("\nNumber of frames ; %u \n",frames);

printf("\n\nPointer before ; %u \n",ptr[0]);


long pl;
for(pl=0;pl<100000;pl++);

if(ptr[1]==NULL)
printf("\nNull pointer 1  allocated\n");
if(ptr[0]==NULL)
printf("\nNull pointer 0 allocated \n");




int check2=1;

snd_pcm_sframes_t size2 =30;
while(1)
	{
		for(i=0;i<2;i++)
		{
		//ptr[i] = (unsigned char*)areas[i].addr + (areas[i].first/8) + offset*(areas[i].step/8);
		
		if(read(dest,ptr[i],120)!=0)
			{
				
				
					if(ptr[i]!=NULL)
					{
						 	
						if(pcmreturn = snd_pcm_mmap_writei(pcm_handle,ptr[i],size2)<0)
							{
								snd_pcm_prepare(pcm_handle);
								printf("\n<<<<<<<Buffer Underrun>>>>>>>>\n");
								break;
							}
					
			

						//	printf("\n%d\n",pcmreturn);
						ptr[i]+=0;
						printf("\n%lu\n",ptr[i]);


					}
											

			}
			else {
				check2=0;
				break;
				}
		}
		
		

		if(check2==0)
		break;
		

			
		
	//	l:break;

	}

	commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames);
	 if(commitres<0)
	         {
	                 printf("\nFrames not committed to memory\n");
	         }

	
}
Esempio n. 8
0
int main()
{

const snd_pcm_channel_area_t *areas;
int size;
unsigned char *buffer;
char *pcm_name;
unsigned int rate = 44100;
int chan;
int rc;
unsigned int  val;
char check;
int pcmreturn;

//Set PCM stream and handle
snd_pcm_t *pcm_handle;
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;

//Set HARDWARE parameters
snd_pcm_hw_params_t *hwparams;


//pcm_name = (char *)malloc(10);
pcm_name = "plughw:0,0";


//allocate memory for hardware
if(snd_pcm_hw_params_malloc(&hwparams)<0)
	{

		fprintf(stderr,"No memory allocated for hardware");
		return(-1);
	
	}



if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0) {
      fprintf(stderr, "Error opening PCM device %s\n", pcm_name);
            return(-1);
	        }

//INITIALIZE HARDWARE WITH CONFIGURATION OF THE SOUNDCARD
	if(snd_pcm_hw_params_any(pcm_handle,hwparams)<0)
		{
			fprintf(stderr,"The hardware device cannot be configured\n");


		}




//SET FORMAT TO 16 BIT LITTLE ENDIAN
snd_pcm_hw_params_set_format(pcm_handle,hwparams,SND_PCM_FORMAT_S16_LE);


/* Two channels (stereo) */
 snd_pcm_hw_params_set_channels(pcm_handle,hwparams,2);

 
    /* 44100 bits/second sampling rate (CD quality) */
      
 if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) {
       fprintf(stderr, "Error setting access.\n");
             return(-1);
	         }


//SETTING RATE ie SAMPLING FREQUENCY

snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0);


//SETTING HARDWARE PARAMETERS

	if(rc=(snd_pcm_hw_params(pcm_handle,hwparams))<0)
		{
			fprintf(stderr,"\nCannot set hardware parameters\n");
			return -1;
		}



//snd_pcm_uframes_t periodsize = 8192;


snd_pcm_uframes_t  frames,offset ;//OF TYPE UNSIGNED LONG
snd_pcm_sframes_t commitres;
frames =32;


//SETTING SOME MORE PARAMETERS

size = frames*4;
//SETTING BUFFER SIZE

/*if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize*2)>>2) < 0) {
      fprintf(stderr, "Error setting buffersize.\n");
            return(-1);


}
*/

int first=0;;
int err;
snd_pcm_sframes_t avail = snd_pcm_avail_update(pcm_handle);
printf("\nNumber of frames available is : %d \n",(int)avail);


//-------------------------------------------------------------------------------------------------------
//<<<<<<<<<<<<<<<<<<<<<<DISPLAYING INFORMATION>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//Buffer size

snd_pcm_hw_params_get_buffer_size(hwparams, (snd_pcm_uframes_t*)&val);
printf("\nThe buffer size is %d \n",val);


//Buffer time

snd_pcm_hw_params_get_buffer_time(hwparams, &val,0);
printf("\nBuffer time is : %d \n",val);


//Period size

snd_pcm_hw_params_get_period_size(hwparams,&frames,0);
printf("\nperiod size : %d \n",(int)frames);



//Periods between buffers


err=snd_pcm_mmap_begin(pcm_handle,&areas,&offset,&frames);


//Periods between buffer

snd_pcm_hw_params_get_periods(hwparams,&val,0);
printf("\n Periods between buffer is : %d \n",val);




//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.

if(err<0)
	{
	printf("\nMMAP error\n");
	return -1;

	
	
	}
else printf("\n%d\n",err);



commitres = snd_pcm_mmap_commit(pcm_handle,offset,frames);
if(commitres<0)
	{
		printf("\nFrames not committed to memory\n");
	}



int dest =  open("sample3.wav",O_RDONLY);

if(dest<0)
	{
		perror("\nFile could not be opened\n");
		return -1;
	}


//int *c = offset;
buffer = (unsigned char *)malloc(1000);



unsigned long buf = offset;
 if(read(dest,&offset,1)<0)
	{
		perror("\nNo destination for read\n");
		return -1;
	}

struct timeval tvbefore,tvafter;
gettimeofday(&tvbefore,NULL);

while(read(dest,buffer,100)!=0);
gettimeofday(&tvafter,NULL);
printf("\nTime taken by read() is %09ld \n",tvafter.tv_usec-tvbefore.tv_usec);



/*


while(1)
	{
		if(read(dest,&offset,80)!=0)
			{
				//fread(buffer,sizeof(buffer),160,f1);
				
				
					{
						if(pcmreturn = snd_pcm_mmap_writei(pcm_handle,&offset,80)<0)
							{
								snd_pcm_prepare(pcm_handle);
								printf("\n<<<<<<<Buffer Underrun>>>>>>>>\n");
								break;
							}
					}
			

		

			}
		else break;

			
	}
*/	
}
Esempio n. 9
0
Player::Player() {
//    printf("Player::Player()\n");
    int rc=0;
    unsigned int val=0;
    int dir=0;
    /* Open PCM device for playback. */
    rc = snd_pcm_open(&(this->m_pHandle), "default",
                SND_PCM_STREAM_PLAYBACK, 0);
    if (rc < 0) {
        printf("unable to open pcm device: %s\n",
                snd_strerror(rc));
        exit(1);
    }

    /* Allocate a hardware parameters object. */
    snd_pcm_hw_params_alloca(&(this->m_pParams));

    /* Fill it in with default values. */
    rc = snd_pcm_hw_params_any(this->m_pHandle, this->m_pParams);
    if (rc < 0) {
        printf("Can not configure this PCM device: %s\n",
                snd_strerror(rc));
        exit(1);
    }
    /* Set the desired hardware parameters. */

    /* Interleaved mode */
    rc = snd_pcm_hw_params_set_access(this->m_pHandle, this->m_pParams,
                    SND_PCM_ACCESS_RW_INTERLEAVED);
    if (rc < 0) {
        printf("Failed to set PCM device to interleaved: %s\n",
                snd_strerror(rc));
        exit(1);
    }
    /* Signed 16-bit little-endian format */
    rc = snd_pcm_hw_params_set_format(this->m_pHandle, this->m_pParams,
                    SND_PCM_FORMAT_S16_LE);
    if (rc < 0) {
        printf("Failed to set PCM device to 16-bit signed PCM: %s\n",
                snd_strerror(rc));
        exit(1);
    }
    /* Two channels (mono) */
    rc = snd_pcm_hw_params_set_channels(this->m_pHandle, this->m_pParams,channels);
    if (rc < 0) {
        printf("Failed to set PCM device to mono: %s\n",
                snd_strerror(rc));
        exit(1);
    }
    /* 44100 bits/second sampling rate (CD quality) */
    val = rate;
    rc = snd_pcm_hw_params_set_rate_near(this->m_pHandle, this->m_pParams,
                    &val, 0);
    if (rc < 0) {
        printf("Failed to set PCM device to sample rate =%d: %s\n",
                rate,snd_strerror(rc));
        exit(1);
    }
	if(val != rate){
		printf("Rate doesn't match (request %iHz, get %iHz\n",rate,val);
		exit(1);
	}


	rc = snd_pcm_hw_params_set_buffer_time_near(this->m_pHandle, this->m_pParams, &buffer_time, &dir);
    if (rc < 0) {
        fprintf(stderr, "Failed to set PCM device to buffer time=%d: %s\n",
                    val,snd_strerror(rc));
        exit(1);
    }

	rc = snd_pcm_hw_params_set_period_time_near(this->m_pHandle, this->m_pParams, &period_time, &dir);
	if (rc < 0) {
        fprintf(stderr, "Failed to set PCM device to period time=%d: %s\n",
                    val,snd_strerror(rc));
        exit(1);
    }
	
	//chunk size
	rc = snd_pcm_hw_params_get_period_size(this->m_pParams, &period_size, &dir);
	if(rc < 0){
		fprintf(stderr, "Failed to get period size for capture: %s\n", snd_strerror(rc));
		exit(1);
	}
	this->m_frames = period_size;

	rc = snd_pcm_hw_params_get_buffer_size(this->m_pParams, &buffer_size);
	if(rc < 0){
		fprintf(stderr, "Failed to get buffer size for capture: %s\n", snd_strerror(rc));
		exit(1);
	}

#ifdef DEBUG
	printf("Recorder alsa driver hw params setting\n");
	printf("period size =%d frames\n", (int)period_size);
	printf("buffer size =%d frames\n", (int)buffer_size);
	snd_pcm_hw_params_get_period_time(this->m_pParams,&val, &dir);
	printf("period time =%d us\n",val);
	snd_pcm_hw_params_get_buffer_time(this->m_pParams,&val, &dir);
	printf("buffer time =%d us\n", val);
	snd_pcm_hw_params_get_periods(this->m_pParams, &val, &dir);
	printf("period per buffer =%d frames\n", val);
#endif	

   /* Write the parameters to the driver */
    rc = snd_pcm_hw_params(this->m_pHandle, this->m_pParams);
    if (rc < 0) {
        printf("unable to set hw parameters: %s\n",
                    snd_strerror(rc));
        exit(1);
    }
    
#ifdef ALSA_OPT
	snd_pcm_sw_params_t *swparams;
	snd_pcm_sw_params_alloca(&swparams);

    /* get the current swparams */
    rc = snd_pcm_sw_params_current(this->m_pHandle, swparams);
    if (rc < 0) {
            printf("Unable to determine current swparams for playback: %s\n", snd_strerror(rc));
            exit(1);
    }
    /* start the transfer when the buffer is almost full: */
    /* (buffer_size / avail_min) * avail_min */
    rc = snd_pcm_sw_params_set_start_threshold(this->m_pHandle, swparams, (buffer_size / period_size) * period_size);
    if (rc < 0) {
            printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(rc));
            exit(1);
    }

    rc = snd_pcm_sw_params_set_avail_min(this->m_pHandle, swparams, period_size);
    if (rc < 0) {
            printf("Unable to set avail min for playback: %s\n", snd_strerror(rc));
            exit(1);
    }
    /* write the parameters to the playback device */
    rc = snd_pcm_sw_params(this->m_pHandle, swparams);
    if (rc < 0) {
            printf("Unable to set sw params for playback: %s\n", snd_strerror(rc));
            exit(1);
    }

#endif
}
Esempio n. 10
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;
}
Esempio n. 11
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;

}
Esempio n. 12
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;
}
Esempio n. 13
0
/**
 * Set up the snd_pcm_t object which was opened by the caller.  Set up
 * the configured settings and the audio format.
 */
static bool
alsa_setup(struct alsa_data *ad, struct audio_format *audio_format,
	   GError **error)
{
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_sw_params_t *swparams;
	unsigned int sample_rate = audio_format->sample_rate;
	unsigned int channels = audio_format->channels;
	snd_pcm_uframes_t alsa_buffer_size;
	snd_pcm_uframes_t alsa_period_size;
	int err;
	const char *cmd = NULL;
	int retry = MPD_ALSA_RETRY_NR;
	unsigned int period_time, period_time_ro;
	unsigned int buffer_time;

	period_time_ro = period_time = ad->period_time;
configure_hw:
	/* configure HW params */
	snd_pcm_hw_params_alloca(&hwparams);
	cmd = "snd_pcm_hw_params_any";
	err = snd_pcm_hw_params_any(ad->pcm, hwparams);
	if (err < 0)
		goto error;

	if (ad->use_mmap) {
		err = snd_pcm_hw_params_set_access(ad->pcm, hwparams,
						   SND_PCM_ACCESS_MMAP_INTERLEAVED);
		if (err < 0) {
			g_warning("Cannot set mmap'ed mode on ALSA device \"%s\":  %s\n",
				  alsa_device(ad), snd_strerror(-err));
			g_warning("Falling back to direct write mode\n");
			ad->use_mmap = false;
		} else
			ad->writei = snd_pcm_mmap_writei;
	}

	if (!ad->use_mmap) {
		cmd = "snd_pcm_hw_params_set_access";
		err = snd_pcm_hw_params_set_access(ad->pcm, hwparams,
						   SND_PCM_ACCESS_RW_INTERLEAVED);
		if (err < 0)
			goto error;
		ad->writei = snd_pcm_writei;
	}

	err = alsa_output_setup_format(ad->pcm, hwparams, audio_format);
	if (err < 0) {
		g_set_error(error, alsa_output_quark(), err,
			    "ALSA device \"%s\" does not support format %s: %s",
			    alsa_device(ad),
			    sample_format_to_string(audio_format->format),
			    snd_strerror(-err));
		return false;
	}

	err = snd_pcm_hw_params_set_channels_near(ad->pcm, hwparams,
						  &channels);
	if (err < 0) {
		g_set_error(error, alsa_output_quark(), err,
			    "ALSA device \"%s\" does not support %i channels: %s",
			    alsa_device(ad), (int)audio_format->channels,
			    snd_strerror(-err));
		return false;
	}
	audio_format->channels = (int8_t)channels;

	err = snd_pcm_hw_params_set_rate_near(ad->pcm, hwparams,
					      &sample_rate, NULL);
	if (err < 0 || sample_rate == 0) {
		g_set_error(error, alsa_output_quark(), err,
			    "ALSA device \"%s\" does not support %u Hz audio",
			    alsa_device(ad), audio_format->sample_rate);
		return false;
	}
	audio_format->sample_rate = sample_rate;

	snd_pcm_uframes_t buffer_size_min, buffer_size_max;
	snd_pcm_hw_params_get_buffer_size_min(hwparams, &buffer_size_min);
	snd_pcm_hw_params_get_buffer_size_max(hwparams, &buffer_size_max);
	unsigned buffer_time_min, buffer_time_max;
	snd_pcm_hw_params_get_buffer_time_min(hwparams, &buffer_time_min, 0);
	snd_pcm_hw_params_get_buffer_time_max(hwparams, &buffer_time_max, 0);
	g_debug("buffer: size=%u..%u time=%u..%u",
		(unsigned)buffer_size_min, (unsigned)buffer_size_max,
		buffer_time_min, buffer_time_max);

	snd_pcm_uframes_t period_size_min, period_size_max;
	snd_pcm_hw_params_get_period_size_min(hwparams, &period_size_min, 0);
	snd_pcm_hw_params_get_period_size_max(hwparams, &period_size_max, 0);
	unsigned period_time_min, period_time_max;
	snd_pcm_hw_params_get_period_time_min(hwparams, &period_time_min, 0);
	snd_pcm_hw_params_get_period_time_max(hwparams, &period_time_max, 0);
	g_debug("period: size=%u..%u time=%u..%u",
		(unsigned)period_size_min, (unsigned)period_size_max,
		period_time_min, period_time_max);

	if (ad->buffer_time > 0) {
		buffer_time = ad->buffer_time;
		cmd = "snd_pcm_hw_params_set_buffer_time_near";
		err = snd_pcm_hw_params_set_buffer_time_near(ad->pcm, hwparams,
							     &buffer_time, NULL);
		if (err < 0)
			goto error;
	} else {
		err = snd_pcm_hw_params_get_buffer_time(hwparams, &buffer_time,
							NULL);
		if (err < 0)
			buffer_time = 0;
	}

	if (period_time_ro == 0 && buffer_time >= 10000) {
		period_time_ro = period_time = buffer_time / 4;

		g_debug("default period_time = buffer_time/4 = %u/4 = %u",
			buffer_time, period_time);
	}

	if (period_time_ro > 0) {
		period_time = period_time_ro;
		cmd = "snd_pcm_hw_params_set_period_time_near";
		err = snd_pcm_hw_params_set_period_time_near(ad->pcm, hwparams,
							     &period_time, NULL);
		if (err < 0)
			goto error;
	}

	cmd = "snd_pcm_hw_params";
	err = snd_pcm_hw_params(ad->pcm, hwparams);
	if (err == -EPIPE && --retry > 0 && period_time_ro > 0) {
		period_time_ro = period_time_ro >> 1;
		goto configure_hw;
	} else if (err < 0)
Esempio n. 14
0
bool
ALSAPCMPlayer::SetParameters(snd_pcm_t &alsa_handle, unsigned sample_rate,
                             bool big_endian_source, unsigned latency,
                             unsigned &channels) {
  /* adoption of alsa-libs's snd_pcm_set_params() function, which is not
   * available on SALSA, with a few detail enhancements. */

  snd_pcm_hw_params_t *hw_params;
  snd_pcm_hw_params_alloca(&hw_params);

  int alsa_error = snd_pcm_hw_params_any(&alsa_handle, hw_params);
  if (alsa_error < 0) {
    LogFormat("snd_pcm_hw_params_any(0x%p, 0x%p) failed: %d - %s",
              &alsa_handle,
              hw_params,
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  /* Try to enable resampling, but do not give up if it fails. Probably we are
   * lucky and our ALSA device supports our sample rate natively. */
  snd_pcm_hw_params_set_rate_resample(&alsa_handle, hw_params, 1);

  alsa_error = snd_pcm_hw_params_set_access(&alsa_handle,
                                            hw_params,
                                            SND_PCM_ACCESS_RW_INTERLEAVED);
  if (0 != alsa_error) {
    LogFormat("snd_pcm_hw_params_set_access(0x%p, 0x%p, "
                  "SND_PCM_ACCESS_RW_INTERLEAVED) failed: %d - %s",
              &alsa_handle,
              hw_params,
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  alsa_error = snd_pcm_hw_params_set_format(&alsa_handle,
                                            hw_params,
                                            big_endian_source
                                                ? SND_PCM_FORMAT_S16_BE
                                                : SND_PCM_FORMAT_S16_LE);
  if (0 != alsa_error) {
    LogFormat("snd_pcm_hw_params_set_format(0x%p, 0x%p, "
                  "%s) failed: %d - %s",
              &alsa_handle,
              hw_params,
              big_endian_source
                  ? "SND_PCM_FORMAT_S16_BE"
                  : "SND_PCM_FORMAT_S16_LE",
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  assert(1 == channels);
  alsa_error = snd_pcm_hw_params_set_channels_near(&alsa_handle,
                                                   hw_params,
                                                   &channels);
  if (0 != alsa_error) {
    LogFormat("snd_pcm_hw_params_set_channels_near(0x%p, 0x%p, 0x%p) "
                  "failed: %d - %s",
              &alsa_handle,
              hw_params,
              &channels,
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  alsa_error = snd_pcm_hw_params_set_rate(&alsa_handle,
                                          hw_params,
                                          sample_rate,
                                          0);
  if (0 != alsa_error) {
    LogFormat("snd_pcm_hw_params_set_rate(0x%p, 0x%p, %u, 0) "
                  "failed: %d - %s",
              &alsa_handle,
              hw_params,
              sample_rate,
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  snd_pcm_uframes_t buffer_size, period_size;

  alsa_error = snd_pcm_hw_params_set_buffer_time_near(&alsa_handle,
                                                      hw_params,
                                                      &latency,
                                                      nullptr);
  if (0 != alsa_error) {
    unsigned period_time = latency / 4;
    alsa_error = snd_pcm_hw_params_set_period_time_near(&alsa_handle,
                                                        hw_params,
                                                        &period_time,
                                                        nullptr);
    if (0 != alsa_error) {
      LogFormat("snd_pcm_hw_params_set_period_time_near(0x%p, 0x%p, 0x%p, "
                    "nullptr) failed: %d - %s",
                &alsa_handle,
                hw_params,
                &period_time,
                alsa_error,
                snd_strerror(alsa_error));
      return false;
    }

    alsa_error = snd_pcm_hw_params_get_period_size(hw_params,
                                                   &period_size,
                                                   nullptr);
    if (0 != alsa_error) {
      LogFormat("snd_pcm_hw_params_get_period_size(0x%p, 0x%p, nullptr) "
                    "failed: %d - %s",
                hw_params,
                &period_size,
                alsa_error,
                snd_strerror(alsa_error));
      return false;
    }

    buffer_size = period_size * 4;
    alsa_error = snd_pcm_hw_params_set_buffer_size_near(&alsa_handle,
                                                        hw_params,
                                                        &buffer_size);
    if (0 != alsa_error) {
      LogFormat("snd_pcm_hw_params_set_buffer_size_near(0x%p, 0x%p, 0x%p) "
                    "failed: %d - %s",
                &alsa_handle,
                hw_params,
                &buffer_size,
                alsa_error,
                snd_strerror(alsa_error));
      return false;
    }

    alsa_error = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
    if (0 != alsa_error) {
      LogFormat("snd_pcm_hw_params_get_buffer_size(0x%p, 0x%p) "
                    "failed: %d - %s",
                hw_params,
                &buffer_size,
                alsa_error,
                snd_strerror(alsa_error));
      return false;
    }
  } else {
    alsa_error = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
    if (0 != alsa_error) {
      LogFormat("snd_pcm_hw_params_get_buffer_size(0x%p, 0x%p) "
                    "failed: %d - %s",
                hw_params,
                &buffer_size,
                alsa_error,
                snd_strerror(alsa_error));
      return false;
    }

    alsa_error = snd_pcm_hw_params_get_buffer_time(hw_params,
                                                   &latency,
                                                   nullptr);
    if (0 != alsa_error) {
      LogFormat("snd_pcm_hw_params_get_buffer_time(0x%p, 0x%p, nullptr) "
                    "failed: %d - %s",
                hw_params,
                &latency,
                alsa_error,
                snd_strerror(alsa_error));
      return false;
    }

    unsigned period_time = latency / 4;
    alsa_error = snd_pcm_hw_params_set_period_time_near(&alsa_handle,
                                                        hw_params,
                                                        &period_time,
                                                        nullptr);
    if (0 != alsa_error) {
      LogFormat("snd_pcm_hw_params_set_period_time_near(0x%p, 0x%p, 0x%p, "
                    "nullptr) failed: %d - %s",
                &alsa_handle,
                hw_params,
                &period_time,
                alsa_error,
                snd_strerror(alsa_error));
      return false;
    }

    alsa_error = snd_pcm_hw_params_get_period_size(hw_params,
                                                   &period_size,
                                                   nullptr);
    if (0 != alsa_error) {
      LogFormat("snd_pcm_hw_params_get_period_size(0x%p, 0x%p, nullptr) "
                    "failed: %d - %s",
                hw_params,
                &period_size,
                alsa_error,
                snd_strerror(alsa_error));
      return false;
    }
  }

  alsa_error = snd_pcm_hw_params(&alsa_handle, hw_params);
  if (0 != alsa_error) {
    LogFormat("snd_pcm_hw_params(0x%p, 0x%p) failed: %d - %s",
              &alsa_handle,
              hw_params,
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  snd_pcm_sw_params_t *sw_params;
  snd_pcm_sw_params_alloca(&sw_params);

  alsa_error = snd_pcm_sw_params_current(&alsa_handle, sw_params);
  if (0 != alsa_error) {
    LogFormat("snd_pcm_sw_params_current(0x%p, 0x%p) failed: %d - %s",
              &alsa_handle,
              sw_params,
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  snd_pcm_uframes_t  start_threshold =
      (buffer_size / period_size) * period_size;
  alsa_error = snd_pcm_sw_params_set_start_threshold(&alsa_handle,
                                                     sw_params,
                                                     start_threshold);
  if (0 != alsa_error) {
    LogFormat("snd_pcm_sw_params_set_start_threshold(0x%p, 0x%p, %u) "
                  "failed: %d - %s",
              &alsa_handle,
              sw_params,
              static_cast<unsigned>(start_threshold),
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  alsa_error = snd_pcm_sw_params_set_avail_min(&alsa_handle,
                                               sw_params,
                                               period_size);
  if (0 != alsa_error) {
    LogFormat("snd_pcm_sw_params_set_avail_min(0x%p, 0x%p, %u) failed: %d - %s",
              &alsa_handle,
              sw_params,
              static_cast<unsigned>(period_size),
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  alsa_error = snd_pcm_sw_params(&alsa_handle, sw_params);
  if (0 != alsa_error) {
    LogFormat("snd_pcm_sw_params(0x%p, 0x%p) failed: %d - %s",
              &alsa_handle,
              sw_params,
              alsa_error,
              snd_strerror(alsa_error));
    return false;
  }

  return true;
}
Esempio n. 15
0
status_t setHardwareParams(alsa_handle_t *handle)
{
    snd_pcm_hw_params_t *hardwareParams;
    status_t err;

    snd_pcm_uframes_t bufferSize = handle->bufferSize;
    unsigned int requestedRate = handle->sampleRate;
    unsigned int latency = handle->latency;

    // snd_pcm_format_description() and snd_pcm_format_name() do not perform
    // proper bounds checking.
    bool validFormat = (static_cast<int> (handle->format)
            > SND_PCM_FORMAT_UNKNOWN) && (static_cast<int> (handle->format)
            <= SND_PCM_FORMAT_LAST);
    const char *formatDesc = validFormat ? snd_pcm_format_description(
            handle->format) : "Invalid Format";
    const char *formatName = validFormat ? snd_pcm_format_name(handle->format)
            : "UNKNOWN";

    if (snd_pcm_hw_params_malloc(&hardwareParams) < 0) {
        LOG_ALWAYS_FATAL("Failed to allocate ALSA hardware parameters!");
        return NO_INIT;
    }

    err = snd_pcm_hw_params_any(handle->handle, hardwareParams);
    if (err < 0) {
        ALOGE("Unable to configure hardware: %s", snd_strerror(err));
        goto done;
    }

    // Set the interleaved read and write format.
    err = snd_pcm_hw_params_set_access(handle->handle, hardwareParams,
            SND_PCM_ACCESS_RW_INTERLEAVED);
    if (err < 0) {
        ALOGE("Unable to configure PCM read/write format: %s",
                snd_strerror(err));
        goto done;
    }

    err = snd_pcm_hw_params_set_format(handle->handle, hardwareParams,
            handle->format);
    if (err < 0) {
        ALOGE("Unable to configure PCM format %s (%s): %s",
                formatName, formatDesc, snd_strerror(err));
        goto done;
    }

    ALOGW("Set %s PCM format to %s (%s)", streamName(handle), formatName, formatDesc);

    err = snd_pcm_hw_params_set_channels(handle->handle, hardwareParams,
            handle->channels);
    if (err < 0) {
        ALOGE("Unable to set channel count to %i: %s",
                handle->channels, snd_strerror(err));
        goto done;
    }

    ALOGW("Using %i %s for %s.", handle->channels,
            handle->channels == 1 ? "channel" : "channels", streamName(handle));

    ALOGW("requestedRate=%d\n", requestedRate);
    err = snd_pcm_hw_params_set_rate_near(handle->handle, hardwareParams,
            &requestedRate, 0);
    ALOGW("returned Rate=%d, handle->rate=%d\n", requestedRate, handle->sampleRate);
    if (err < 0)
        ALOGE("Unable to set %s sample rate to %u: %s",
                streamName(handle), handle->sampleRate, snd_strerror(err));
    else if (requestedRate != handle->sampleRate)
        // Some devices have a fixed sample rate, and can not be changed.
        // This may cause resampling problems; i.e. PCM playback will be too
        // slow or fast.
        ALOGW("Requested rate (%u HZ) does not match actual rate (%u HZ)",
                handle->sampleRate, requestedRate);
    else
        ALOGI("Set %s sample rate to %u HZ", streamName(handle), requestedRate);

#ifdef DISABLE_HARWARE_RESAMPLING
    // Disable hardware re-sampling.
    err = snd_pcm_hw_params_set_rate_resample(handle->handle,
            hardwareParams,
            static_cast<int>(resample));
    if (err < 0) {
        ALOGE("Unable to %s hardware resampling: %s",
                resample ? "enable" : "disable",
                snd_strerror(err));
        goto done;
    }
#endif

    // Make sure we have at least the size we originally wanted
    err = snd_pcm_hw_params_set_buffer_size_near(handle->handle, hardwareParams,
            &bufferSize);

    if (err < 0) {
        ALOGE("Unable to set buffer size to %d:  %s",
                (int)bufferSize, snd_strerror(err));
        goto done;
    }

    // Setup buffers for latency
    err = snd_pcm_hw_params_set_buffer_time_near(handle->handle,
            hardwareParams, &latency, NULL);
    if (err < 0) {
        /* That didn't work, set the period instead */
        unsigned int periodTime = latency / 4;
        err = snd_pcm_hw_params_set_period_time_near(handle->handle,
                hardwareParams, &periodTime, NULL);
        if (err < 0) {
            ALOGE("Unable to set the period time for latency: %s", snd_strerror(err));
            goto done;
        }
        snd_pcm_uframes_t periodSize;
        err = snd_pcm_hw_params_get_period_size(hardwareParams, &periodSize,
                NULL);
        if (err < 0) {
            ALOGE("Unable to get the period size for latency: %s", snd_strerror(err));
            goto done;
        }
        bufferSize = periodSize * 4;
        if (bufferSize < handle->bufferSize) bufferSize = handle->bufferSize;
        err = snd_pcm_hw_params_set_buffer_size_near(handle->handle,
                hardwareParams, &bufferSize);
        if (err < 0) {
            ALOGE("Unable to set the buffer size for latency: %s", snd_strerror(err));
            goto done;
        }
    } else {
        // OK, we got buffer time near what we expect. See what that did for bufferSize.
        err = snd_pcm_hw_params_get_buffer_size(hardwareParams, &bufferSize);
        if (err < 0) {
            ALOGE("Unable to get the buffer size for latency: %s", snd_strerror(err));
            goto done;
        }
        // Does set_buffer_time_near change the passed value? It should.
        err = snd_pcm_hw_params_get_buffer_time(hardwareParams, &latency, NULL);
        if (err < 0) {
            ALOGE("Unable to get the buffer time for latency: %s", snd_strerror(err));
            goto done;
        }
        unsigned int periodTime = latency / 4;
        err = snd_pcm_hw_params_set_period_time_near(handle->handle,
                hardwareParams, &periodTime, NULL);
        if (err < 0) {
            ALOGE("Unable to set the period time for latency: %s", snd_strerror(err));
            goto done;
        }
    }

    ALOGI("Buffer size: %d", (int)bufferSize);
    ALOGI("Latency: %d", (int)latency);

    handle->bufferSize = bufferSize;
    handle->latency = latency;

    // Commit the hardware parameters back to the device.
    err = snd_pcm_hw_params(handle->handle, hardwareParams);
    if (err < 0) ALOGE("Unable to set hardware parameters: %s", snd_strerror(err));

    done:
    snd_pcm_hw_params_free(hardwareParams);

    return err;
}
Esempio n. 16
0
static size_t
alsa_configure (void)
{
  //<init:
  size_t chunk_bytes, bits_per_sample, bits_per_frame = 0;
  snd_pcm_uframes_t chunk_size, buffer_size = 0;
  snd_pcm_hw_params_t *params;
  unsigned int rate = DEFAULT_SPEED;
  int err;
  snd_pcm_hw_params_alloca (&params);
  //>
  //<defaults:

  err = snd_pcm_hw_params_any (AHandle, params);
  if (err < 0)
    {
      fprintf (stderr,
               "Broken configuration for this PCM: no configurations available");
      exit (EXIT_FAILURE);
    }

  //>
  //<Format:

  err = snd_pcm_hw_params_set_format (AHandle, params, DEFAULT_FORMAT);
  if (err < 0)
    {
      fprintf (stderr, "Sample format non available");
      exit (EXIT_FAILURE);
    }

  //>
  //<Channels:

  err = snd_pcm_hw_params_set_channels (AHandle, params, 1);
  if (err < 0)
    {
      fprintf (stderr, "Channels count non available");
      exit (EXIT_FAILURE);
    }

  //>
  //<Rate:

  err = snd_pcm_hw_params_set_rate_near (AHandle, params, &rate, 0);
  assert (err >= 0);

  //>
  //<Access Mode:
  err = snd_pcm_hw_params_set_access (AHandle, params,
                                      SND_PCM_ACCESS_RW_INTERLEAVED);
  if (err < 0)
    {
      fprintf (stderr, "Access type not available");
      exit (EXIT_FAILURE);
    }
  //>
  //< Set things explicitly if DEBUG
#ifdef DEBUG

  //<Compute buffer_time:
  unsigned int period_time = 0;
  unsigned int buffer_time = 0;
  snd_pcm_uframes_t period_frames = 0;
  snd_pcm_uframes_t buffer_frames = 0;
  // affected by defined buffer_size  (e.g. via asoundrc)
  if (buffer_time == 0 && buffer_frames == 0)
    {
      err = snd_pcm_hw_params_get_buffer_time (params, &buffer_time, 0);
      assert (err >= 0);
      if (buffer_time > 500000) //usecs
        buffer_time = 500000;
    }
  //>
  //<Compute period_time:

  if (period_time == 0 && period_frames == 0)
    {
      if (buffer_time > 0)
        period_time = buffer_time / 4;
      else
        period_frames = buffer_frames / 4;
    }
  if (period_time > 0)
    err = snd_pcm_hw_params_set_period_time_near (AHandle, params,
                                                  &period_time, 0);
  else
    err = snd_pcm_hw_params_set_period_size_near (AHandle, params,
                                                  &period_frames, 0);
  assert (err >= 0);
  if (buffer_time > 0)
    {
      err = snd_pcm_hw_params_set_buffer_time_near (AHandle, params,
                                                    &buffer_time, 0);
    }
  else
    {
      err = snd_pcm_hw_params_set_buffer_size_near (AHandle, params,
                                                    &buffer_frames);
    }
  assert (err >= 0);

  //>
#endif

  //>
  //<Commit hw params:
  err = snd_pcm_hw_params (AHandle, params);
  if (err < 0)
    {
      fprintf (stderr, "Unable to install hw params:");
      exit (EXIT_FAILURE);
    }
  //>
  //<finalize chunk_size and buffer_size:

  snd_pcm_hw_params_get_period_size (params, &chunk_size, 0);
  snd_pcm_hw_params_get_buffer_size (params, &buffer_size);
  if (chunk_size == buffer_size)
    {
      fprintf (stderr, "Can't use period equal to buffer size (%lu == %lu)",
               chunk_size, buffer_size);
      exit (EXIT_FAILURE);
    }

  //>
  //< If DEBUG: SW Params Configure transfer:

#ifdef DEBUG
  size_t n;
  snd_pcm_uframes_t xfer_align;
  snd_pcm_uframes_t start_threshold, stop_threshold;
  int start_delay = 5;
  int stop_delay = 0;
  snd_pcm_sw_params_t *swParams;
  snd_pcm_sw_params_alloca (&swParams);
  snd_pcm_sw_params_current (AHandle, swParams);
  err = snd_pcm_sw_params_get_xfer_align (swParams, &xfer_align);
  if (err < 0)
    {
      fprintf (stderr, "Unable to obtain xfer align\n");
      exit (EXIT_FAILURE);
    }
  // round up to closest transfer boundary
  n = (buffer_size / xfer_align) * xfer_align;
  if (start_delay <= 0)
    {
      start_threshold =
        (snd_pcm_uframes_t) (n + (double) rate * start_delay / 1000000);
    }
  else
    start_threshold =
      (snd_pcm_uframes_t) ((double) rate * start_delay / 1000000);
  if (start_threshold < 1)
    start_threshold = 1;
  if (start_threshold > n)
    start_threshold = n;
  err =
    snd_pcm_sw_params_set_start_threshold (AHandle, swParams,
                                           start_threshold);
  assert (err >= 0);
  if (stop_delay <= 0)
    stop_threshold =
      (snd_pcm_uframes_t) (buffer_size +
                           (double) rate * stop_delay / 1000000);
  else
    stop_threshold =
      (snd_pcm_uframes_t) ((double) rate * stop_delay / 1000000);
  err =
    snd_pcm_sw_params_set_stop_threshold (AHandle, swParams, stop_threshold);
  assert (err >= 0);

  err = snd_pcm_sw_params_set_xfer_align (AHandle, swParams, xfer_align);
  assert (err >= 0);

  if (snd_pcm_sw_params (AHandle, swParams) < 0)
    {
      fprintf (stderr, "unable to install sw params:");
      exit (EXIT_FAILURE);
    }
#endif

  //>
  bits_per_sample = snd_pcm_format_physical_width (DEFAULT_FORMAT);
  bits_per_frame = bits_per_sample * 1; //mono
  chunk_bytes = chunk_size * bits_per_frame / 8;
  return chunk_bytes;
}
bool QAudioOutputPrivate::open()
{
    if(opened)
        return true;

#ifdef DEBUG_AUDIO
    QTime now(QTime::currentTime());
    qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
#endif
    timeStamp.restart();
    elapsedTimeOffset = 0;

    int dir;
    int err=-1;
    int count=0;
    unsigned int freakuency=settings.frequency();

    QString dev = QLatin1String(m_device.constData());
    QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput);
    if(dev.compare(QLatin1String("default")) == 0) {
#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
        dev = QLatin1String(devices.first().constData());
#else
        dev = QLatin1String("hw:0,0");
#endif
    } else {
#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
        dev = QLatin1String(m_device);
#else
        int idx = 0;
        char *name;

        QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData());

	while(snd_card_get_name(idx,&name) == 0) {
            if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0)
                break;
            idx++;
	}
        dev = QString(QLatin1String("hw:%1,0")).arg(idx);
#endif
    }

    // Step 1: try and open the device
    while((count < 5) && (err < 0)) {
        err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0);
        if(err < 0)
            count++;
    }
    if (( err < 0)||(handle == 0)) {
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        return false;
    }
    snd_pcm_nonblock( handle, 0 );

    // Step 2: Set the desired HW parameters.
    snd_pcm_hw_params_alloca( &hwparams );

    bool fatal = false;
    QString errMessage;
    unsigned int chunks = 8;

    err = snd_pcm_hw_params_any( handle, hwparams );
    if ( err < 0 ) {
        fatal = true;
        errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_any: err = %1").arg(err);
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_access( handle, hwparams, access );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_access: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = setFormat();
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_format: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_channels: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &freakuency, 0 );
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
        if ( err < 0 ) {
            fatal = true;
                errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err);
        }
    }
    if ( !fatal ) {
        err = snd_pcm_hw_params(handle, hwparams);
        if ( err < 0 ) {
            fatal = true;
            errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params: err = %1").arg(err);
        }
    }
    if( err < 0) {
        qWarning()<<errMessage;
        errorState = QAudio::OpenError;
        deviceState = QAudio::StoppedState;
        return false;
    }
    snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
    buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
    snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir);
    period_size = snd_pcm_frames_to_bytes(handle,period_frames);
    snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
    snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);

    // Step 3: Set the desired SW parameters.
    snd_pcm_sw_params_t *swparams;
    snd_pcm_sw_params_alloca(&swparams);
    snd_pcm_sw_params_current(handle, swparams);
    snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames);
    snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames);
    snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames);
    snd_pcm_sw_params(handle, swparams);

    // Step 4: Prepare audio
    if(audioBuffer == 0)
        audioBuffer = new char[snd_pcm_frames_to_bytes(handle,buffer_frames)];
    snd_pcm_prepare( handle );
    snd_pcm_start(handle);

    // Step 5: Setup callback and timer fallback
    snd_async_add_pcm_handler(&ahandler, handle, async_callback, this);
    bytesAvailable = bytesFree();

    // Step 6: Start audio processing
    timer->start(period_time/1000);

    clockStamp.restart();
    timeStamp.restart();
    elapsedTimeOffset = 0;
    errorState  = QAudio::NoError;
    totalTimeValue = 0;
    opened = true;

    return true;
}
Esempio n. 18
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;
}