Example #1
0
/**
 * \brief Reset all parameters
 * \param pcm ordinary PCM handle
 * \return 0 on success otherwise a negative error code
 */
int sndo_pcm_param_reset(sndo_pcm_t *pcm)
{
	int err;

	err = sndo_pcm_drain(pcm);
	if (err < 0)
		return err;
	pcm->initialized = 0;
	if (pcm->playback) {
		err = snd_pcm_hw_params_any(pcm->playback, pcm->p_hw_params);
		if (err < 0)
			return err;
		err = snd_pcm_sw_params_current(pcm->playback, pcm->p_sw_params);
		if (err < 0)
			return err;
	}
	if (pcm->capture) {
		err = snd_pcm_hw_params_any(pcm->capture, pcm->c_hw_params);
		if (err < 0)
			return err;
		err = snd_pcm_sw_params_current(pcm->capture, pcm->c_sw_params);
		if (err < 0)
			return err;
	}
	return 0;
}
Example #2
0
static void audio_renderer_init() {
  int rc;
  decoder = opus_decoder_create(SAMPLE_RATE, CHANNEL_COUNT, &rc);

  snd_pcm_hw_params_t *hw_params;
  snd_pcm_sw_params_t *sw_params;
  snd_pcm_uframes_t period_size = FRAME_SIZE * CHANNEL_COUNT * 2;
  snd_pcm_uframes_t buffer_size = 12 * period_size;
  unsigned int sampleRate = SAMPLE_RATE;

  /* Open PCM device for playback. */
  CHECK_RETURN(snd_pcm_open(&handle, audio_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK))

  /* Set hardware parameters */
  CHECK_RETURN(snd_pcm_hw_params_malloc(&hw_params));
  CHECK_RETURN(snd_pcm_hw_params_any(handle, hw_params));
  CHECK_RETURN(snd_pcm_hw_params_set_access(handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED));
  CHECK_RETURN(snd_pcm_hw_params_set_format(handle, hw_params, SND_PCM_FORMAT_S16_LE));
  CHECK_RETURN(snd_pcm_hw_params_set_rate_near(handle, hw_params, &sampleRate, NULL));
  CHECK_RETURN(snd_pcm_hw_params_set_channels(handle, hw_params, CHANNEL_COUNT));
  CHECK_RETURN(snd_pcm_hw_params_set_buffer_size_near(handle, hw_params, &buffer_size));
  CHECK_RETURN(snd_pcm_hw_params_set_period_size_near(handle, hw_params, &period_size, NULL));
  CHECK_RETURN(snd_pcm_hw_params(handle, hw_params));
  snd_pcm_hw_params_free(hw_params);

  /* Set software parameters */
  CHECK_RETURN(snd_pcm_sw_params_malloc(&sw_params));
  CHECK_RETURN(snd_pcm_sw_params_current(handle, sw_params));
  CHECK_RETURN(snd_pcm_sw_params_set_start_threshold(handle, sw_params, buffer_size - period_size));
  CHECK_RETURN(snd_pcm_sw_params_set_avail_min(handle, sw_params, period_size));
  CHECK_RETURN(snd_pcm_sw_params(handle, sw_params));
  snd_pcm_sw_params_free(sw_params);

  CHECK_RETURN(snd_pcm_prepare(handle));
}
// returns 1 if successful
int setSWParams(AlsaPcmInfo* info) {
    int ret;

    /* get the current swparams */
    ret = snd_pcm_sw_params_current(info->handle, info->swParams);
    if (ret < 0) {
        ERROR1("Unable to determine current swparams: %s\n", snd_strerror(ret));
        return FALSE;
    }
    /* never start the transfer automatically */
    if (!setStartThresholdNoCommit(info, FALSE /* don't use threshold */)) {
        return FALSE;
    }

    /* allow the transfer when at least period_size samples can be processed */
    ret = snd_pcm_sw_params_set_avail_min(info->handle, info->swParams, info->periodSize);
    if (ret < 0) {
        ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
        return FALSE;
    }
    /* align all transfers to 1 sample */
    ret = snd_pcm_sw_params_set_xfer_align(info->handle, info->swParams, 1);
    if (ret < 0) {
        ERROR1("Unable to set transfer align: %s\n", snd_strerror(ret));
        return FALSE;
    }
    /* write the parameters to the playback device */
    ret = snd_pcm_sw_params(info->handle, info->swParams);
    if (ret < 0) {
        ERROR1("Unable to set sw params: %s\n", snd_strerror(ret));
        return FALSE;
    }
    return TRUE;
}
Example #4
0
static void alsa_set_sw_params(struct alsa_dev *dev, snd_pcm_t *handle,
			       int period, int thres)
{
	int ret;
	snd_pcm_sw_params_t *sw_params;

	ret = snd_pcm_sw_params_malloc(&sw_params);
	if (ret < 0)
		syslog_panic("Cannot allocate software parameters: %s\n",
			     snd_strerror(ret));
	ret = snd_pcm_sw_params_current(handle, sw_params);
	if (ret < 0)
		syslog_panic("Cannot initialize software parameters: %s\n",
			     snd_strerror(ret));
	ret = snd_pcm_sw_params_set_avail_min(handle, sw_params, period);
	if (ret < 0)
		syslog_panic("Cannot set minimum available count: %s\n",
			     snd_strerror(ret));
	if (thres) {
		ret = snd_pcm_sw_params_set_start_threshold(handle, sw_params,
							    period);
		if (ret < 0)
			syslog_panic("Cannot set start mode: %s\n",
				     snd_strerror(ret));
		
	}
	ret = snd_pcm_sw_params(handle, sw_params);
	if (ret < 0)
		syslog_panic("Cannot set software parameters: %s\n",
			     snd_strerror(ret));
	snd_pcm_sw_params_free(sw_params);
}
int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams)
{
        int err;

        /* get the current swparams */
        err = snd_pcm_sw_params_current(handle, swparams);
        if (err < 0) {
                printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
                return err;
        }
        /* start the transfer when the buffer is almost full: */
        /* (buffer_size / avail_min) * avail_min */
        //err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (buffer_size / period_size) * period_size);
        err = snd_pcm_sw_params_set_start_threshold(handle, swparams, period_size * periods - arnold_frame_size);
        if (err < 0) {
                printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
                return err;
        }
        /* allow the transfer when at least period_size samples can be processed */
        err = snd_pcm_sw_params_set_avail_min(handle, swparams, arnold_frame_size);
        if (err < 0) {
                printf("Unable to set avail min for playback: %s\n", snd_strerror(err));
                return err;
        }
        /* write the parameters to the playback device */
        err = snd_pcm_sw_params(handle, swparams);
        if (err < 0) {
                printf("Unable to set sw params for playback: %s\n", snd_strerror(err));
                return err;
        }
        return 0;
}
Example #6
0
snd_pcm_t *open_pcm(char *pcm_name) {

    snd_pcm_t *playback_handle;
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_sw_params_t *sw_params;
            
    if (snd_pcm_open (&playback_handle, pcm_name, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        fprintf (stderr, "cannot open audio device %s\n", pcm_name);
        exit (1);
    }
    snd_pcm_hw_params_alloca(&hw_params);
    snd_pcm_hw_params_any(playback_handle, hw_params);
    snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_S16_LE);
    snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, 44100, 0);
    snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2);
    snd_pcm_hw_params_set_periods(playback_handle, hw_params, 2, 0);
    snd_pcm_hw_params_set_period_size(playback_handle, hw_params, BUFSIZE, 0);
    snd_pcm_hw_params(playback_handle, hw_params);
    snd_pcm_sw_params_alloca(&sw_params);
    snd_pcm_sw_params_current(playback_handle, sw_params);
    snd_pcm_sw_params_set_avail_min(playback_handle, sw_params, BUFSIZE);
    snd_pcm_sw_params(playback_handle, sw_params);
    return(playback_handle);
}
Example #7
0
int VoiceStreamer::setparams_set(snd_pcm_t *handle, snd_pcm_hw_params_t *params,
      snd_pcm_sw_params_t *swparams, const char *id) {
   int err;
   snd_pcm_uframes_t val;

   if ((err = snd_pcm_hw_params(handle, params)) < 0) {
      printf("Unable to set hw params for %s: %s\n", id, snd_strerror(err));
      return err;
   }
   if ((err = snd_pcm_sw_params_current(handle, swparams)) < 0) {
      printf("Unable to determine current swparams for %s: %s\n", id,
            snd_strerror(err));
      return err;
   }
   if ((err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 
               0x7fffffff)) < 0) {
      printf("Unable to set start threshold mode for %s: %s\n", id,
            snd_strerror(err));
      return err;
   }
   val = 4;
   if ((err = snd_pcm_sw_params_set_avail_min(handle, swparams, val)) < 0) {
      printf("Unable to set sw params for %s: %s\n", id, snd_strerror(err));
      return err;
   }

   return 0;
}
Example #8
0
static int set_sw_params(snd_pcm_t *pcm,
                         snd_pcm_sw_params_t *sw_params,
                         snd_spcm_xrun_type_t xrun_type)
{
    int err;

    err = snd_pcm_sw_params_current(pcm, sw_params);
    if (err < 0)
        return err;
    err = snd_pcm_sw_params_set_start_threshold(pcm, sw_params, (pcm->buffer_size / pcm->period_size) * pcm->period_size);
    if (err < 0)
        return err;
    err = snd_pcm_sw_params_set_avail_min(pcm, sw_params, pcm->period_size);
    if (err < 0)
        return err;
    switch (xrun_type) {
    case SND_SPCM_XRUN_STOP:
        err = snd_pcm_sw_params_set_stop_threshold(pcm, sw_params, pcm->buffer_size);
        break;
    case SND_SPCM_XRUN_IGNORE:
        err = snd_pcm_sw_params_set_stop_threshold(pcm, sw_params, pcm->boundary);
        break;
    default:
        return -EINVAL;
    }
    if (err < 0)
        return err;
    err = snd_pcm_sw_params_set_xfer_align(pcm, sw_params, 1);
    if (err < 0)
        return err;
    err = snd_pcm_sw_params(pcm, sw_params);
    if (err < 0)
        return err;
    return 0;
}
Example #9
0
static BOOL tsmf_alsa_set_format(ITSMFAudioDevice *audio,
								 UINT32 sample_rate, UINT32 channels, UINT32 bits_per_sample)
{
	int error;
	snd_pcm_uframes_t frames;
	snd_pcm_hw_params_t *hw_params;
	snd_pcm_sw_params_t *sw_params;
	TSMFAlsaAudioDevice *alsa = (TSMFAlsaAudioDevice *) audio;
	if(!alsa->out_handle)
		return FALSE;
	snd_pcm_drop(alsa->out_handle);
	alsa->actual_rate = alsa->source_rate = sample_rate;
	alsa->actual_channels = alsa->source_channels = channels;
	alsa->bytes_per_sample = bits_per_sample / 8;
	error = snd_pcm_hw_params_malloc(&hw_params);
	if(error < 0)
	{
		WLog_ERR(TAG, "snd_pcm_hw_params_malloc failed");
		return FALSE;
	}
	snd_pcm_hw_params_any(alsa->out_handle, hw_params);
	snd_pcm_hw_params_set_access(alsa->out_handle, hw_params,
								 SND_PCM_ACCESS_RW_INTERLEAVED);
	snd_pcm_hw_params_set_format(alsa->out_handle, hw_params,
								 SND_PCM_FORMAT_S16_LE);
	snd_pcm_hw_params_set_rate_near(alsa->out_handle, hw_params,
									&alsa->actual_rate, NULL);
	snd_pcm_hw_params_set_channels_near(alsa->out_handle, hw_params,
										&alsa->actual_channels);
	frames = sample_rate;
	snd_pcm_hw_params_set_buffer_size_near(alsa->out_handle, hw_params,
										   &frames);
	snd_pcm_hw_params(alsa->out_handle, hw_params);
	snd_pcm_hw_params_free(hw_params);
	error = snd_pcm_sw_params_malloc(&sw_params);
	if(error < 0)
	{
		WLog_ERR(TAG, "snd_pcm_sw_params_malloc");
		return FALSE;
	}
	snd_pcm_sw_params_current(alsa->out_handle, sw_params);
	snd_pcm_sw_params_set_start_threshold(alsa->out_handle, sw_params,
										  frames / 2);
	snd_pcm_sw_params(alsa->out_handle, sw_params);
	snd_pcm_sw_params_free(sw_params);
	snd_pcm_prepare(alsa->out_handle);
	DEBUG_TSMF("sample_rate %d channels %d bits_per_sample %d",
			   sample_rate, channels, bits_per_sample);
	DEBUG_TSMF("hardware buffer %d frames", (int)frames);
	if((alsa->actual_rate != alsa->source_rate) ||
			(alsa->actual_channels != alsa->source_channels))
	{
		DEBUG_TSMF("actual rate %d / channel %d is different "
				   "from source rate %d / channel %d, resampling required.",
				   alsa->actual_rate, alsa->actual_channels,
				   alsa->source_rate, alsa->source_channels);
	}
	return TRUE;
}
Example #10
0
static av_cold int audio_read_header(AVFormatContext *s1,
                                     AVFormatParameters *ap)
{
    AlsaData *s = s1->priv_data;
    AVStream *st;
    int ret;
    enum CodecID codec_id;
    snd_pcm_sw_params_t *sw_params;

    st = av_new_stream(s1, 0);
    if (!st) {
        av_log(s1, AV_LOG_ERROR, "Cannot add stream\n");

        return AVERROR(ENOMEM);
    }
    codec_id    = s1->audio_codec_id;

    ret = ff_alsa_open(s1, SND_PCM_STREAM_CAPTURE, &s->sample_rate, s->channels,
        &codec_id);
    if (ret < 0) {
        return AVERROR(EIO);
    }

    if (snd_pcm_type(s->h) != SND_PCM_TYPE_HW)
        av_log(s1, AV_LOG_WARNING,
               "capture with some ALSA plugins, especially dsnoop, "
               "may hang.\n");

    ret = snd_pcm_sw_params_malloc(&sw_params);
    if (ret < 0) {
        av_log(s1, AV_LOG_ERROR, "cannot allocate software parameters structure (%s)\n",
               snd_strerror(ret));
        goto fail;
    }

    snd_pcm_sw_params_current(s->h, sw_params);
    snd_pcm_sw_params_set_tstamp_mode(s->h, sw_params, SND_PCM_TSTAMP_ENABLE);

    ret = snd_pcm_sw_params(s->h, sw_params);
    snd_pcm_sw_params_free(sw_params);
    if (ret < 0) {
        av_log(s1, AV_LOG_ERROR, "cannot install ALSA software parameters (%s)\n",
               snd_strerror(ret));
        goto fail;
    }

    /* take real parameters */
    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id    = codec_id;
    st->codec->sample_rate = s->sample_rate;
    st->codec->channels    = s->channels;
    av_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */

    return 0;

fail:
    snd_pcm_close(s->h);
    return AVERROR(EIO);
}
Example #11
0
static int
set_params(struct alsa_device_data * alsa_data)
{
	snd_pcm_hw_params_t * hw_params;
	snd_pcm_sw_params_t * sw_params;
	int error;
	snd_pcm_uframes_t frames;

	snd_pcm_drop(alsa_data->out_handle);

	error = snd_pcm_hw_params_malloc(&hw_params);
	if (error < 0)
	{
		LLOGLN(0, ("set_params: snd_pcm_hw_params_malloc failed"));
		return 1;
	}
	snd_pcm_hw_params_any(alsa_data->out_handle, hw_params);
	snd_pcm_hw_params_set_access(alsa_data->out_handle, hw_params,
		SND_PCM_ACCESS_RW_INTERLEAVED);
	snd_pcm_hw_params_set_format(alsa_data->out_handle, hw_params,
		alsa_data->format);
	snd_pcm_hw_params_set_rate_near(alsa_data->out_handle, hw_params,
		&alsa_data->actual_rate, NULL);
	snd_pcm_hw_params_set_channels_near(alsa_data->out_handle, hw_params,
		&alsa_data->actual_channels);
	frames = alsa_data->actual_rate * 4;
	snd_pcm_hw_params_set_buffer_size_near(alsa_data->out_handle, hw_params,
		&frames);
	snd_pcm_hw_params(alsa_data->out_handle, hw_params);
	snd_pcm_hw_params_free(hw_params);

	error = snd_pcm_sw_params_malloc(&sw_params);
	if (error < 0)
	{
		LLOGLN(0, ("set_params: snd_pcm_sw_params_malloc"));
		return 1;
	}
	snd_pcm_sw_params_current(alsa_data->out_handle, sw_params);
	snd_pcm_sw_params_set_start_threshold(alsa_data->out_handle, sw_params,
		frames / 2);
	snd_pcm_sw_params(alsa_data->out_handle, sw_params);
	snd_pcm_sw_params_free(sw_params);

	snd_pcm_prepare(alsa_data->out_handle);

	LLOGLN(10, ("set_params: hardware buffer %d frames, playback buffer %.2g seconds",
		(int)frames, (double)frames / 2.0 / (double)alsa_data->actual_rate));
	if ((alsa_data->actual_rate != alsa_data->source_rate) ||
		(alsa_data->actual_channels != alsa_data->source_channels))
	{
		LLOGLN(0, ("set_params: actual rate %d / channel %d is different from source rate %d / channel %d, resampling required.",
			alsa_data->actual_rate, alsa_data->actual_channels, alsa_data->source_rate, alsa_data->source_channels));
	}
	return 0;
}
Example #12
0
int AudioAlsa::setSWParams()
{
	int err;

	// get the current swparams
	if( ( err = snd_pcm_sw_params_current( m_handle, m_swParams ) ) < 0 )
	{
		printf( "Unable to determine current swparams for playback: %s"
						"\n", snd_strerror( err ) );
		return err;
	}

	// start the transfer when a period is full
	if( ( err = snd_pcm_sw_params_set_start_threshold( m_handle,
					m_swParams, m_periodSize ) ) < 0 )
	{
		printf( "Unable to set start threshold mode for playback: %s\n",
							snd_strerror( err ) );
		return err;
	}

	// allow the transfer when at least m_periodSize samples can be
	// processed
	if( ( err = snd_pcm_sw_params_set_avail_min( m_handle, m_swParams,
							m_periodSize ) ) < 0 )
	{
		printf( "Unable to set avail min for playback: %s\n",
							snd_strerror( err ) );
		return err;
	}

	// align all transfers to 1 sample
	
#if SND_LIB_VERSION < ((1<<16)|(0)|16)
	if( ( err = snd_pcm_sw_params_set_xfer_align( m_handle,
							m_swParams, 1 ) ) < 0 )
	{
		printf( "Unable to set transfer align for playback: %s\n",
							snd_strerror( err ) );
		return err;
	}
#endif

	// write the parameters to the playback device
	if( ( err = snd_pcm_sw_params( m_handle, m_swParams ) ) < 0 )
	{
		printf( "Unable to set sw params for playback: %s\n",
							snd_strerror( err ) );
		return err;
	}

	return 0;	// all ok
}
Example #13
0
void mixer_open()
{
	memset(&channels, 0, sizeof(channels));
	int err = snd_pcm_open(&pcm, "default", SND_PCM_STREAM_PLAYBACK, 0);
	if (err < 0)
	{
		printf("Failed to open pcm device: %s\n", snd_strerror(err));
		exit(1);
	}
	
	unsigned int rate = 44100;
	snd_pcm_hw_params_t *hw_params = 0;
	snd_pcm_hw_params_alloca(&hw_params);
	snd_pcm_hw_params_any(pcm, hw_params);
	snd_pcm_hw_params_set_rate_resample(pcm, hw_params, 0);
	snd_pcm_hw_params_set_access(pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
	snd_pcm_hw_params_set_format(pcm, hw_params, SND_PCM_FORMAT_S16_LE);
	snd_pcm_hw_params_set_rate_near(pcm, hw_params, &rate, 0);
	snd_pcm_hw_params_set_channels(pcm, hw_params, 2);
	snd_pcm_hw_params_set_period_size(pcm, hw_params, BUFFER_SIZE, 0);
	snd_pcm_hw_params_set_buffer_size(pcm, hw_params, BUFFER_SIZE * 4);
	
	err = snd_pcm_hw_params(pcm, hw_params);
	if (err < 0)
	{
		printf("Failed to apply pcm hardware settings: %s\n", snd_strerror(err));
		exit(1);
	}
	
	snd_pcm_sw_params_t *sw_params = 0;
	snd_pcm_sw_params_alloca(&sw_params);
	snd_pcm_sw_params_current(pcm, sw_params);
	snd_pcm_sw_params_set_avail_min(pcm, sw_params, BUFFER_SIZE * 4);
	err = snd_pcm_sw_params(pcm, sw_params);
	if (err < 0)
	{
		printf("Failed to apply pcm software settings: %s\n", snd_strerror(err));
		exit(1);
	}
	
	err = snd_pcm_prepare(pcm);
	if (err < 0)
	{
		printf("Failed to prepare pcm interface: %s\n", snd_strerror(err));
		exit(1);
	}
	
	memset(delay_left, 0, sizeof(delay_left));
	memset(delay_right, 0, sizeof(delay_right));
}
Example #14
0
static int setparams_set(snd_pcm_t *handle,
                         snd_pcm_hw_params_t *params,
                         snd_pcm_sw_params_t *swparams,
                         snd_pcm_uframes_t start_treshold,
                         const char *id)
{
    int err;

    err = snd_pcm_hw_params(handle, params);
    if (err < 0) {
        fprintf(error_fp, "alsa: Unable to set hw params for %s: %s\n",
                id, snd_strerror(err));
        return err;
    }
    err = snd_pcm_sw_params_current(handle, swparams);
    if (err < 0) {
        fprintf(error_fp, "alsa: Unable to determine current swparams for %s: %s\n",
                id, snd_strerror(err));
        return err;
    }
    err = snd_pcm_sw_params_set_start_threshold(handle, swparams,
            start_treshold);
    if (err < 0) {
        fprintf(error_fp, "alsa: Unable to set start threshold mode for %s: %s\n",
                id, snd_strerror(err));
        return err;
    }

    err = snd_pcm_sw_params_set_avail_min(handle, swparams, 4);
    if (err < 0) {
        fprintf(error_fp, "alsa: Unable to set avail min for %s: %s\n",
                id, snd_strerror(err));
        return err;
    }

    err = snd_pcm_sw_params_set_tstamp_mode(handle, swparams, SND_PCM_TSTAMP_ENABLE);
    if (err < 0) {
        fprintf(error_fp, "alsa: Unable to enable timestamps for %s: %s\n",
                id, snd_strerror(err));
    }

    err = snd_pcm_sw_params(handle, swparams);
    if (err < 0) {
        fprintf(error_fp, "alsa: Unable to set sw params for %s: %s\n",
                id, snd_strerror(err));
        return err;
    }
    return 0;
}
Example #15
0
/**************************************************************************************
 * set_swparams
 * history: (1) 2014 03 30 mhb
 *
 **************************************************************************************/
static int set_swparams(snd_pcm_t *handle, 
                        snd_pcm_sw_params_t *swparams)
{
    int err;
    /* get the current swparams */
    err = snd_pcm_sw_params_current(handle, swparams);
    if (err < 0) 
    {
        printf("Unable to determine current swparams : %s\n", snd_strerror(err));
        return err;
    }
    /* start the transfer when the buffer is almost full: */
    /* (buffer_size / avail_min) * avail_min */
    err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (buffer_size / period_size) * period_size);
    //err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 3*period_size);// mhb|  修改此值,太小程序会卡死
    if (err < 0) 
    {
        printf("Unable to set start threshold mode : %s\n", snd_strerror(err));
        return err;
    }
    /* allow the transfer when at least period_size samples can be processed */
    /* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
    err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_event ? buffer_size : period_size);
    //err = snd_pcm_sw_params_set_avail_min(handle, swparams, 0);//mhb
    if (err < 0) 
    {
        printf("Unable to set avail min : %s\n", snd_strerror(err));
        return err;
    }
    /* enable period events when requested */
    if (period_event) 
    {
        err = snd_pcm_sw_params_set_period_event(handle, swparams, 1);
        if (err < 0) 
        {
            printf("Unable to set period event: %s\n", snd_strerror(err));
            return err;
        }
    }
    /* write the parameters to the playback device */
    err = snd_pcm_sw_params(handle, swparams);
    if (err < 0) 
    {
        printf("Unable to set sw params : %s\n", snd_strerror(err));
        return err;
    }
    return 0;
}
int
set_mic_swparams(snd_pcm_t *handle) 
{
    // set software params

    snd_pcm_sw_params_t *swparams;
    snd_pcm_sw_params_alloca(&swparams);

    /* get the current swparams */
    int ret = snd_pcm_sw_params_current(handle, swparams);
    if (ret < 0) {
        fprintf(stderr, 
	    "Unable to determine current swparams for mic: %s\n", 
	    snd_strerror(ret));
        return ret;
    }

    /* allow transfer when at least period_frames can be processed */

    ret = snd_pcm_sw_params_set_avail_min(handle, swparams, 
	get_period_frames(handle));

    if (ret < 0) {
        fprintf(stderr, "Unable to set avail min for mic: %s\n", 
	    snd_strerror(ret));
        return ret;
    }

    /* align all transfers to 1 sample */
    ret = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1);
    if (ret < 0) {
        fprintf(stderr, "Unable to set transfer align for mic: %s\n", 
	    snd_strerror(ret));
        return ret;
    }

    /* write the parameters to the microphone device */
    ret = snd_pcm_sw_params(handle, swparams);
    if (ret < 0) {
        fprintf(stderr, "Unable to set sw params for mic: %s\n", 
	    snd_strerror(ret));
        return ret;
    }
	
    dump_swparams(handle);
    return 0;
}
Example #17
0
static int alsa_set_hwparams()
{
	snd_pcm_hw_params_t *hwp;
	snd_pcm_sw_params_t *swp;
	int dir = 1;
	unsigned period_time;
	snd_pcm_uframes_t buffer_size, period_size;

	snd_pcm_hw_params_alloca(&hwp);
	snd_pcm_sw_params_alloca(&swp);

	// ALSA bug? If we request 44100 Hz, it rounds the value up to 48000...
	alsa_hw.rate--;

	if (alsa_error("hw_params_any", snd_pcm_hw_params_any(alsa_hw.handle, hwp))
	    || alsa_error("hw_params_set_format", snd_pcm_hw_params_set_format(alsa_hw.handle, hwp, alsa_hw.format))
	    || alsa_error("hw_params_set_channels",
			  snd_pcm_hw_params_set_channels(alsa_hw.handle, hwp, alsa_hw.num_channels))
	    || alsa_error("hw_params_set_rate_near",
			  snd_pcm_hw_params_set_rate_near(alsa_hw.handle, hwp, &alsa_hw.rate, &dir))
	    || alsa_error("hw_params_set_access",
			  snd_pcm_hw_params_set_access(alsa_hw.handle, hwp, SND_PCM_ACCESS_RW_INTERLEAVED))
	    || alsa_error("hw_params_set_buffer_time_near",
			  snd_pcm_hw_params_set_buffer_time_near(alsa_hw.handle, hwp, &alsa_hw.buffer_time, 0)))
		return -1;

	/* How often to call our SIGIO handler (~40Hz) */
	period_time = alsa_hw.buffer_time / 4;
	if (alsa_error
	    ("hw_params_set_period_time_near",
	     snd_pcm_hw_params_set_period_time_near(alsa_hw.handle, hwp, &period_time, &dir))
	    || alsa_error("hw_params_get_buffer_size", snd_pcm_hw_params_get_buffer_size(hwp, &buffer_size))
	    || alsa_error("hw_params_get_period_size", snd_pcm_hw_params_get_period_size(hwp, &period_size, 0))
	    || alsa_error("hw_params", snd_pcm_hw_params(alsa_hw.handle, hwp)))
		return -1;

	snd_pcm_sw_params_current(alsa_hw.handle, swp);
	if (alsa_error
	    ("sw_params_set_start_threshold", snd_pcm_sw_params_set_start_threshold(alsa_hw.handle, swp, period_size))
	    || alsa_error("sw_params_set_avail_min", snd_pcm_sw_params_set_avail_min(alsa_hw.handle, swp, period_size))
	    || alsa_error("sw_params", snd_pcm_sw_params(alsa_hw.handle, swp)))
		return -1;

	return 0;
}
static int drvHostALSAAudioSetThreshold(snd_pcm_t *phPCM,
                                        snd_pcm_uframes_t threshold)
{
    snd_pcm_sw_params_t *pSWParms = NULL;
    snd_pcm_sw_params_alloca(&pSWParms);
    if (!pSWParms)
        return VERR_NO_MEMORY;

    int rc;
    do
    {
        int err = snd_pcm_sw_params_current(phPCM, pSWParms);
        if (err < 0)
        {
            LogRel(("ALSA: Failed to get current software parameters for threshold: %s\n",
                    snd_strerror(err)));
            rc = VERR_ACCESS_DENIED;
            break;
        }

        err = snd_pcm_sw_params_set_start_threshold(phPCM, pSWParms, threshold);
        if (err < 0)
        {
            LogRel(("ALSA: Failed to set software threshold to %ld: %s\n",
                    threshold, snd_strerror(err)));
            rc = VERR_ACCESS_DENIED;
            break;
        }

        err = snd_pcm_sw_params(phPCM, pSWParms);
        if (err < 0)
        {
            LogRel(("ALSA: Failed to set new software parameters for threshold: %s\n",
                    snd_strerror(err)));
            rc = VERR_ACCESS_DENIED;
            break;
        }

        LogFlowFunc(("Setting threshold to %RU32\n", threshold));
        rc = VINF_SUCCESS;
    }
    while (0);

    return rc;
}
Example #19
0
static int
laudio_alsa_set_start_threshold(snd_pcm_uframes_t threshold)
{
  snd_pcm_sw_params_t *sw_params;
  int ret;

  ret = snd_pcm_sw_params_malloc(&sw_params);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_LAUDIO, "Could not allocate sw params: %s\n", snd_strerror(ret));

      goto out_fail;
    }

  ret = snd_pcm_sw_params_current(hdl, sw_params);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_LAUDIO, "Could not retrieve current sw params: %s\n", snd_strerror(ret));

      goto out_fail;
    }

  ret = snd_pcm_sw_params_set_start_threshold(hdl, sw_params, threshold);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_LAUDIO, "Could not set start threshold: %s\n", snd_strerror(ret));

      goto out_fail;
    }

  ret = snd_pcm_sw_params(hdl, sw_params);
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_LAUDIO, "Could not set sw params: %s\n", snd_strerror(ret));

      goto out_fail;
    }

  return 0;

 out_fail:
  snd_pcm_sw_params_free(sw_params);

  return -1;
}
Example #20
0
int
sa_stream_get_min_write(sa_stream_t *s, size_t *size) {
  int r;
  snd_pcm_uframes_t threshold;
  snd_pcm_sw_params_t* swparams;
  if (s == NULL || s->output_unit == NULL) {
    return SA_ERROR_NO_INIT;
  }
  snd_pcm_sw_params_alloca(&swparams);
  snd_pcm_sw_params_current(s->output_unit, swparams);
  r = snd_pcm_sw_params_get_start_threshold(swparams, &threshold);
  if (r < 0) {
    return SA_ERROR_NO_INIT;
  }
  *size = snd_pcm_frames_to_bytes(s->output_unit, threshold);

  return SA_SUCCESS;
}
/* setup alsa data transfer behavior */
static inline int alsa_set_swparams(ao_alsa_internal *internal)
{
	snd_pcm_sw_params_t   *params;
	int err;

	/* allocate the software parameter structure */
	snd_pcm_sw_params_alloca(&params);

	/* fetch the current software parameters */
	internal->cmd = "snd_pcm_sw_params_current";
	err = snd_pcm_sw_params_current(internal->pcm_handle, params);
	if (err < 0)
		return err;

	/* allow transfers to start when there is one period */
	internal->cmd = "snd_pcm_sw_params_set_start_threshold";
	err = snd_pcm_sw_params_set_start_threshold(internal->pcm_handle,
			params, internal->period_size);
	if (err < 0)
		return err;

	/* require a minimum of one full transfer in the buffer */
	internal->cmd = "snd_pcm_sw_params_set_avail_min";
	err = snd_pcm_sw_params_set_avail_min(internal->pcm_handle, params,
			internal->period_size);
	if (err < 0)
		return err;

	/* do not align transfers */
	internal->cmd = "snd_pcm_sw_params_set_xfer_align";
	err = snd_pcm_sw_params_set_xfer_align(internal->pcm_handle, params, 1);
	if (err < 0)
		return err;

	/* commit the params structure to ALSA */
	internal->cmd = "snd_pcm_sw_params";
	err = snd_pcm_sw_params(internal->pcm_handle, params);
	if (err < 0)
		return err;

	return 1;
}
// On error return a negative value
// If the requested buffer size can be served return 0,
// otherwise return the number of 16 bit words contained in the obtained buffer
mp_sint32 AudioDriver_ALSA::initDevice(mp_sint32 periodSizeAsSamples, const mp_uint32 mixFrequency, MasterMixer* mixer)
{
	snd_pcm_sw_params_t *swparams;
	snd_pcm_uframes_t buffer_size;
	int err;

	snd_pcm_sw_params_alloca(&swparams);

	if ((err = snd_pcm_open(&pcm, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
		fprintf(stderr, "ALSA: Failed to open device 'default' (%s)\n", snd_strerror(err));
		return -1;
	}

	if ((err = snd_pcm_set_params(pcm,
		SND_PCM_FORMAT_S16,
		SND_PCM_ACCESS_MMAP_INTERLEAVED,
		2, // channels
		mixFrequency,
		0, // disallow soft resampling
		(2000000 * static_cast<unsigned long long> (periodSizeAsSamples)) / mixFrequency)) < 0)
			// period size in uS
	{
		fprintf(stderr, "ALSA: Playback open error (%s)\nALSA: Is your mixer frequency correct? Try 48000Hz\nALSA: If you are seeing \"Access type not available for PLAYBACK\" then your audio driver does not support MMAP access, and will not work with this version of MilkyTracker using the ALSA driver (try SDL instead).\n", snd_strerror(err));
		return -1;
	}

	snd_pcm_prepare(pcm);
	period_size = periodSizeAsSamples * 2;
	snd_pcm_get_params(pcm, &buffer_size, &period_size);
	stream = new char[period_size * 2];
	printf("ALSA: Period size = %lu frames (requested %i), buffer size = %lu frames\n", period_size, periodSizeAsSamples / 2, buffer_size);

	/* get the current swparams */
	err = snd_pcm_sw_params_current(pcm, swparams);
	if (err < 0) {
		fprintf(stderr, "ALSA: Unable to determine current swparams for playback: %s\n", snd_strerror(err));
		return -1;
	}

	AudioDriverBase::initDevice(period_size * 2, mixFrequency, mixer);
	return period_size * 2;		// 2 = number of channels
}
Example #23
0
/* Get the pcm boundary value. */
static int get_boundary(snd_pcm_t *pcm, snd_pcm_uframes_t *boundary)
{
	snd_pcm_sw_params_t *sw_params;
	int rc;

	snd_pcm_sw_params_alloca(&sw_params);

	rc = snd_pcm_sw_params_current(pcm, sw_params);
	if (rc < 0) {
		fprintf(stderr, "sw_params_current: %s\n", snd_strerror(rc));
		return rc;
	}

	rc = snd_pcm_sw_params_get_boundary(sw_params, boundary);
	if (rc < 0) {
		fprintf(stderr, "get_boundary: %s\n", snd_strerror(rc));
		return rc;
	}

	return 0;
}
Example #24
0
void AlsaRenderer::SetupSwParams()
{
    snd_pcm_sw_params_t* params;

    /* allocate a software parameters object */
    snd_pcm_sw_params_malloc(&params);

    /* get the current swparams */
    snd_pcm_sw_params_current(m_PcmHandle, params);

    /* round up to closest transfer boundary */
    snd_pcm_sw_params_set_start_threshold(m_PcmHandle, params, 1);

    /* require a minimum of one full transfer in the buffer */
    snd_pcm_sw_params_set_avail_min(m_PcmHandle, params, 1);

    snd_pcm_sw_params(m_PcmHandle, params);

    /* free */
    snd_pcm_sw_params_free(params);
}
Example #25
0
static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int period, int nperiods) {
	int err;

	/* get the current swparams */
	err = snd_pcm_sw_params_current(handle, swparams);
	if (err < 0) {
		printf("Unable to determine current swparams for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* start the transfer when the buffer is full */
	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, period );
	if (err < 0) {
		printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
		return err;
	}
	err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, -1 );
	if (err < 0) {
		printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* allow the transfer when at least period_size samples can be processed */
	err = snd_pcm_sw_params_set_avail_min(handle, swparams, 1 );
	if (err < 0) {
		printf("Unable to set avail min for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* align all transfers to 1 sample */
	err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1);
	if (err < 0) {
		printf("Unable to set transfer align for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* write the parameters to the playback device */
	err = snd_pcm_sw_params(handle, swparams);
	if (err < 0) {
		printf("Unable to set sw params for capture: %s\n", snd_strerror(err));
		return err;
	}
	return 0;
}
int setparams_set(snd_pcm_t *handle,
		  snd_pcm_hw_params_t *params,
		  snd_pcm_sw_params_t *swparams,
		  const char *id)
{
	int err;
	snd_pcm_uframes_t val;

	err = snd_pcm_hw_params(handle, params);
	if (err < 0) {
		printf("Unable to set hw params for %s: %s\n", id, snd_strerror(err));
		return err;
	}
	err = snd_pcm_sw_params_current(handle, swparams);
	if (err < 0) {
		printf("Unable to determine current swparams for %s: %s\n", id, snd_strerror(err));
		return err;
	}
	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0x7fffffff);
	if (err < 0) {
		printf("Unable to set start threshold mode for %s: %s\n", id, snd_strerror(err));
		return err;
	}
	if (!block)
		val = 4;
	else
		snd_pcm_hw_params_get_period_size(params, &val, NULL);
	err = snd_pcm_sw_params_set_avail_min(handle, swparams, val);
	if (err < 0) {
		printf("Unable to set avail min for %s: %s\n", id, snd_strerror(err));
		return err;
	}
	err = snd_pcm_sw_params(handle, swparams);
	if (err < 0) {
		printf("Unable to set sw params for %s: %s\n", id, snd_strerror(err));
		return err;
	}
	return 0;
}
Example #27
0
bool CAESinkALSA::InitializeSW(AEAudioFormat &format)
{
  snd_pcm_sw_params_t *sw_params;
  snd_pcm_uframes_t boundary;

  snd_pcm_sw_params_alloca(&sw_params);
  memset(sw_params, 0, snd_pcm_sw_params_sizeof());

  snd_pcm_sw_params_current              (m_pcm, sw_params);
  snd_pcm_sw_params_set_start_threshold  (m_pcm, sw_params, INT_MAX);
  snd_pcm_sw_params_set_silence_threshold(m_pcm, sw_params, 0);
  snd_pcm_sw_params_get_boundary         (sw_params, &boundary);
  snd_pcm_sw_params_set_silence_size     (m_pcm, sw_params, boundary);
  snd_pcm_sw_params_set_avail_min        (m_pcm, sw_params, format.m_frames);

  if (snd_pcm_sw_params(m_pcm, sw_params) < 0)
  {
    CLog::Log(LOGERROR, "CAESinkALSA::InitializeSW - Failed to set the parameters");
    return false;
  }

  return true;
}
Example #28
0
snd_pcm_t *open_pcm(char *pcm_name) {
    snd_pcm_t *playback_handle;
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_sw_params_t *sw_params;
    if (snd_pcm_open (&playback_handle, pcm_name, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        fprintf (stderr, "cannot open audio device %s\n", pcm_name);
      return NULL;//it seems greedy and wants exclusive control?!
    }
    snd_pcm_hw_params_alloca(&hw_params);
    snd_pcm_hw_params_any(playback_handle, hw_params);
    snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_S16_LE);
    snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &rate, 0);
    snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2);
    snd_pcm_hw_params_set_periods(playback_handle, hw_params, 2, 0);
    snd_pcm_hw_params_set_period_size(playback_handle, hw_params, BUFSAMPS, 0);
    snd_pcm_hw_params(playback_handle, hw_params);
    snd_pcm_sw_params_alloca(&sw_params);
    snd_pcm_sw_params_current(playback_handle, sw_params);
    snd_pcm_sw_params_set_avail_min(playback_handle, sw_params, BUFSAMPS);
    snd_pcm_sw_params(playback_handle, sw_params);
    return(playback_handle);
}
Example #29
0
bool AudioInputALSA::PrepSwParams(void)
{
    snd_pcm_sw_params_t* swparams;
    snd_pcm_sw_params_alloca(&swparams);
    snd_pcm_uframes_t boundary;
    if (AlsaBad(snd_pcm_sw_params_current(pcm_handle, swparams),
                "failed to get swparams"))
        return false;
    if (AlsaBad(snd_pcm_sw_params_get_boundary(swparams, &boundary),
                "failed to get boundary"))
        return false;
    // explicit start, not auto start
    if (AlsaBad(snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams,
                boundary), "failed to set start threshold"))
        return false;
    if (AlsaBad(snd_pcm_sw_params_set_stop_threshold(pcm_handle, swparams,
                boundary), "failed to set stop threshold"))
        return false;
    if (AlsaBad(snd_pcm_sw_params(pcm_handle, swparams),
                "failed to set software parameters"))
        return false;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return 0;
}