コード例 #1
0
ファイル: linear.c プロジェクト: CSCLOG/beaglebone
static void init_data(struct linear_priv *data,
		      snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
{
	int src_le, dst_le, src_bytes, dst_bytes;

	src_bytes = snd_pcm_format_width(src_format) / 8;
	dst_bytes = snd_pcm_format_width(dst_format) / 8;
	src_le = snd_pcm_format_little_endian(src_format) > 0;
	dst_le = snd_pcm_format_little_endian(dst_format) > 0;

	data->dst_bytes = dst_bytes;
	data->cvt_endian = src_le != dst_le;
	data->copy_bytes = src_bytes < dst_bytes ? src_bytes : dst_bytes;
	if (src_le) {
		data->copy_ofs = 4 - data->copy_bytes;
		data->src_ofs = src_bytes - data->copy_bytes;
	} else
		data->src_ofs = snd_pcm_format_physical_width(src_format) / 8 -
			src_bytes;
	if (dst_le)
		data->dst_ofs = 4 - data->dst_bytes;
	else
		data->dst_ofs = snd_pcm_format_physical_width(dst_format) / 8 -
			dst_bytes;
	if (snd_pcm_format_signed(src_format) !=
	    snd_pcm_format_signed(dst_format)) {
		if (dst_le)
			data->flip = (__force u32)cpu_to_le32(0x80000000);
		else
			data->flip = (__force u32)cpu_to_be32(0x80000000);
	}
}
コード例 #2
0
ファイル: pcm_dshare.c プロジェクト: ysei/uclinux-2
static void share_areas(snd_pcm_direct_t *dshare,
		      const snd_pcm_channel_area_t *src_areas,
		      const snd_pcm_channel_area_t *dst_areas,
		      snd_pcm_uframes_t src_ofs,
		      snd_pcm_uframes_t dst_ofs,
		      snd_pcm_uframes_t size)
{
	unsigned int chn, dchn, channels;
	snd_pcm_format_t format;

	channels = dshare->channels;
	format = dshare->shmptr->s.format;
	if (dshare->interleaved) {
		unsigned int fbytes = snd_pcm_format_physical_width(format) / 8;
		memcpy(((char *)dst_areas[0].addr) + (dst_ofs * channels * fbytes),
		       ((char *)src_areas[0].addr) + (src_ofs * channels * fbytes),
		       size * channels * fbytes);
	} else {
		for (chn = 0; chn < channels; chn++) {
			dchn = dshare->bindings ? dshare->bindings[chn] : chn;
			snd_pcm_area_copy(&dst_areas[dchn], dst_ofs, &src_areas[chn], src_ofs, size, format);

		}
	}
}
コード例 #3
0
ファイル: server.c プロジェクト: hello2mhb/mhbcode
/**********************************************************************************
* pcm_init()
*
***********************************************************************************/
static void pcm_init(void)
{
    int err;
    snd_pcm_hw_params_t *hwparams;
    snd_pcm_sw_params_t *swparams;
    snd_pcm_hw_params_alloca(&hwparams);
    snd_pcm_sw_params_alloca(&swparams);

    if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) 
    {
        printf("Playback open error: %s\n", snd_strerror(err));
    }
    if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) 
    {
        printf("Setting of hwparams failed: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    if ((err = set_swparams(handle, swparams)) < 0) 
    {
        printf("Setting of swparams failed: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }       
    /*分配空间 period的空间,period指向空间首地址*/
    period_size_real = period_size * channels * snd_pcm_format_physical_width(format) / 8;//snd_pcm_format_physical_width:return bits needed to store a PCM sample.
    period = malloc(period_size_real);
    if (period == NULL) 
    {
        printf("No enough memory\n");
        exit(EXIT_FAILURE);
    }
    fprintf(stdout,"pcm_init sucess !\n");
}
コード例 #4
0
static int saarb_i2s_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	int width = snd_pcm_format_physical_width(params_format(params));
	int ret;

	ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_NET_PLL, 0,
				     PM860X_CLK_DIR_OUT);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, PM860X_CLK_DIR_OUT);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;
	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);

	return ret;
}
コード例 #5
0
ファイル: copy.c プロジェクト: acassis/emlinux-ssd1935
int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
			      struct snd_pcm_plugin_format *src_format,
			      struct snd_pcm_plugin_format *dst_format,
			      struct snd_pcm_plugin **r_plugin)
{
	int err;
	struct snd_pcm_plugin *plugin;
	int width;

	snd_assert(r_plugin != NULL, return -ENXIO);
	*r_plugin = NULL;

	snd_assert(src_format->format == dst_format->format, return -ENXIO);
	snd_assert(src_format->rate == dst_format->rate, return -ENXIO);
	snd_assert(src_format->channels == dst_format->channels, return -ENXIO);

	width = snd_pcm_format_physical_width(src_format->format);
	snd_assert(width > 0, return -ENXIO);

	err = snd_pcm_plugin_build(plug, "copy", src_format, dst_format,
				   0, &plugin);
	if (err < 0)
		return err;
	plugin->transfer = copy_transfer;
	*r_plugin = plugin;
	return 0;
}
コード例 #6
0
ファイル: pcm.c プロジェクト: 543872407/Linux_SourceCode
int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area,
			 snd_pcm_uframes_t dst_offset,
			 unsigned int samples, snd_pcm_format_t format)
{
	char *dst;
	unsigned int dst_step;
	int width;

	if (!dst_area->addr)
		return 0;
	width = snd_pcm_format_physical_width(format);
	if (width < 8)
		return area_silence_4bit(dst_area, dst_offset, samples, format);
	dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
	if (dst_area->step == (unsigned int) width) {
		snd_pcm_format_set_silence(format, dst, samples);
		return 0;
	}
	dst_step = dst_area->step / 8;
	while (samples-- > 0) {
		snd_pcm_format_set_silence(format, dst, 1);
		dst += dst_step;
	}
	return 0;
}
コード例 #7
0
int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
			      struct snd_pcm_plugin_format *src_format,
			      struct snd_pcm_plugin_format *dst_format,
			      struct snd_pcm_plugin **r_plugin)
{
	int err;
	struct snd_pcm_plugin *plugin;
	int width;

	if (snd_BUG_ON(!r_plugin))
		return -ENXIO;
	*r_plugin = NULL;

	if (snd_BUG_ON(src_format->format != dst_format->format))
		return -ENXIO;
	if (snd_BUG_ON(src_format->rate != dst_format->rate))
		return -ENXIO;
	if (snd_BUG_ON(src_format->channels != dst_format->channels))
		return -ENXIO;

	width = snd_pcm_format_physical_width(src_format->format);
	if (snd_BUG_ON(width <= 0))
		return -ENXIO;

	err = snd_pcm_plugin_build(plug, "copy", src_format, dst_format,
				   0, &plugin);
	if (err < 0)
		return err;
	plugin->transfer = copy_transfer;
	*r_plugin = plugin;
	return 0;
}
コード例 #8
0
ファイル: pcm_linear.c プロジェクト: Boshin/workspace
int snd_pcm_linear_get_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
{
	int sign, width, pwidth, endian;
	sign = (snd_pcm_format_signed(src_format) != 
		snd_pcm_format_signed(dst_format));
#ifdef SND_LITTLE_ENDIAN
	endian = snd_pcm_format_big_endian(src_format);
#else
	endian = snd_pcm_format_little_endian(src_format);
#endif
	if (endian < 0)
		endian = 0;
	pwidth = snd_pcm_format_physical_width(src_format);
	width = snd_pcm_format_width(src_format);
	if (pwidth == 24) {
		switch (width) {
		case 24:
			width = 0; break;
		case 20:
			width = 1; break;
		case 18:
		default:
			width = 2; break;
		}
		return width * 4 + endian * 2 + sign + 16;
	} else {
		width = width / 8 - 1;
		return width * 4 + endian * 2 + sign;
	}
}
コード例 #9
0
ファイル: ordinary_pcm.c プロジェクト: xenyinzen/lx_toolset
/**
 * \brief Set stream format
 * \param pcm ordinary PCM handle
 * \param rate requested channels
 * \param used_rate returned real channels
 * \return 0 on success otherwise a negative error code
 */
int sndo_pcm_param_format(sndo_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_subformat_t subformat)
{
	int err;
	
	if (subformat != SND_PCM_SUBFORMAT_STD)
		return -EINVAL;
	err = snd_pcm_format_physical_width(format);
	if (err < 0)
		return err;
	if (err % 8)
		return -EINVAL;
	err = sndo_pcm_setup(pcm);
	if (err < 0)
		return err;
	if (pcm->playback) {
		err = snd_pcm_hw_params_set_format(pcm->capture, pcm->p_hw_params, format);
		if (err < 0) {
			SNDERR("cannot set requested format for the playback direction");
			return err;
		}
	}
	if (pcm->capture) {
		err = snd_pcm_hw_params_set_format(pcm->capture, pcm->c_hw_params, format);
		if (err < 0) {
			SNDERR("cannot set requested format for the capture direction");
			return err;
		}
	}
	return 0;
}
コード例 #10
0
static void play_callback(snd_async_handler_t *ahandler)
{
	snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler);
	int err;
	signed short *samples_buf;
	samples_buf = malloc((period_size * channels * snd_pcm_format_physical_width(format)) / 8);
	if(file_capture == 0)
	{
		printf("err file\r\n");
	}
	struct timeval oldtv;
	struct timeval tv;
	/*avasounil = snd_pcm_avail_update(handle);*/

	if ((err = snd_pcm_readi (handle, samples_buf,period_size)) != period_size)
	 {
		fprintf (stderr, "read from audio interface failed (%s)\n",snd_strerror (err));
		exit (1);
	 }
	else
	{
		 gettimeofday(&tv,NULL);
  		 printf("time %lu\n",(tv.tv_sec-oldtv.tv_sec)*1000000+tv.tv_usec-oldtv.tv_usec);
		 oldtv = tv;
	 	 fwrite(samples_buf,2,910,file_capture);		
	}		
}
コード例 #11
0
ファイル: zylonite.c プロジェクト: ReneNyffenegger/linux
static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
				    struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	unsigned int pll_out = 0;
	unsigned int wm9713_div = 0;
	int ret = 0;
	int rate = params_rate(params);
	int width = snd_pcm_format_physical_width(params_format(params));

	/* Only support ratios that we can generate neatly from the AC97
	 * based master clock - in particular, this excludes 44.1kHz.
	 * In most applications the voice DAC will be used for telephony
	 * data so multiples of 8kHz will be the common case.
	 */
	switch (rate) {
	case 8000:
		wm9713_div = 12;
		break;
	case 16000:
		wm9713_div = 6;
		break;
	case 48000:
		wm9713_div = 2;
		break;
	default:
		/* Don't support OSS emulation */
		return -EINVAL;
	}

	/* Add 1 to the width for the leading clock cycle */
	pll_out = rate * (width + 1) * 8;

	ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, pll_out);
	if (ret < 0)
		return ret;

	if (clk_pout)
		ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV,
					     WM9713_PCMDIV(wm9713_div));
	else
		ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
					     WM9713_PCMDIV(wm9713_div));
	if (ret < 0)
		return ret;

	return 0;
}
コード例 #12
0
ファイル: local_sound.c プロジェクト: TA1DB/rtl_hpsdr
static struct snd_format*
snd_format_alloc(int rate, int channels) {
	struct snd_format* f = malloc(sizeof(struct snd_format));

	f->format = SND_PCM_FORMAT_S16_BE;
	f->rate = rate;
	f->channels = channels;
	f->sample_bits = snd_pcm_format_physical_width(f->format);
	f->bps = (rate * f->sample_bits * channels) >> 3;

	return f;
}
コード例 #13
0
static int snd_rpi_iqaudio_dac_hw_params(struct snd_pcm_substream *substream,
				       struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
// NOT USED	struct snd_soc_dai *codec_dai = rtd->codec_dai;
// NOT USED	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

	unsigned int sample_bits =
		snd_pcm_format_physical_width(params_format(params));

	return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
}
コード例 #14
0
ファイル: newPlayer1.c プロジェクト: cty222/Note
static void set_params(void)
{
	hwparams.format=SND_PCM_FORMAT_S16_LE;
        hwparams.channels=2;
        hwparams.rate=44100;

	snd_pcm_hw_params_t *params;
	snd_pcm_sw_params_t *swparams;

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

	snd_pcm_hw_params_any(handle, params);
	snd_pcm_hw_params_set_format(handle, params, hwparams.format);
	snd_pcm_hw_params_set_channels(handle, params, hwparams.channels);
	snd_pcm_hw_params_set_rate_near(handle, params, &hwparams.rate, 0);

	buffer_time=0;
	snd_pcm_hw_params_get_buffer_time_max(params,&buffer_time, 0);

	period_time=125000;
	snd_pcm_hw_params_set_period_time_near(handle, params,&period_time, 0);

	buffer_time = 500000;
	snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, 0);
	
	/*monotonic = */snd_pcm_hw_params_is_monotonic(params);
        /*can_pause = */snd_pcm_hw_params_can_pause(params);

	
	printf("sizeof(params) : %d\n",sizeof(params));

        snd_pcm_hw_params(handle, params);

        snd_pcm_uframes_t buffer_size;
	snd_pcm_hw_params_get_period_size(params, &chunk_size, 0);

	size_t n=chunk_size;

	snd_pcm_sw_params_set_avail_min(handle, swparams, n);


	snd_pcm_uframes_t start_threshold, stop_threshold;	
	start_threshold=22050;
	snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
	stop_threshold=22050;
	snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
	
	snd_pcm_format_physical_width(hwparams.format);
	
}
コード例 #15
0
ファイル: pcm_plugin.c プロジェクト: xricson/knoppix
static int snd_pcm_plugin_alloc(snd_pcm_plugin_t *plugin, snd_pcm_uframes_t frames)
{
	snd_pcm_plugin_format_t *format;
	ssize_t width;
	size_t size;
	unsigned int channel;
	snd_pcm_plugin_channel_t *c;

	if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		format = &plugin->src_format;
	} else {
		format = &plugin->dst_format;
	}
	if ((width = snd_pcm_format_physical_width(format->format)) < 0)
		return width;
	size = frames * format->channels * width;
	snd_assert((size % 8) == 0, return -ENXIO);
	size /= 8;
	if (plugin->buf_frames < frames) {
		if (plugin->buf)
			vfree(plugin->buf);
		plugin->buf = vmalloc(size);
		plugin->buf_frames = frames;
	}
	if (!plugin->buf) {
		plugin->buf_frames = 0;
		return -ENOMEM;
	}
	c = plugin->buf_channels;
	if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
		for (channel = 0; channel < format->channels; channel++, c++) {
			c->frames = frames;
			c->enabled = 1;
			c->wanted = 0;
			c->area.addr = plugin->buf;
			c->area.first = channel * width;
			c->area.step = format->channels * width;
		}
	} else if (plugin->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
		snd_assert((size % format->channels) == 0,);
		size /= format->channels;
		for (channel = 0; channel < format->channels; channel++, c++) {
			c->frames = frames;
			c->enabled = 1;
			c->wanted = 0;
			c->area.addr = plugin->buf + (channel * size);
			c->area.first = 0;
			c->area.step = width;
		}
	} else
コード例 #16
0
static int a2dp_params(snd_pcm_ioplug_t * io, snd_pcm_hw_params_t * params)
{
	snd_pcm_a2dp_t *a2dp = io->private_data;
	unsigned int period_bytes;

	a2dp->frame_bytes = (snd_pcm_format_physical_width(io->format) * io->channels) / 8;

	period_bytes = io->period_size * a2dp->frame_bytes;

//	DBG("format %s rate %d channels %d", snd_pcm_format_name(io->format), io->rate, io->channels);

//	DBG("frame_bytes %d period_bytes %d period_size %ld buffer_size %ld", a2dp->frame_bytes, period_bytes, io->period_size, io->buffer_size);

	return 0;
}
コード例 #17
0
ファイル: omap-pcm.c プロジェクト: 19Dan01/linux
/* sDMA supports only 1, 2, and 4 byte transfer elements. */
static void omap_pcm_limit_supported_formats(void)
{
	int i;

	for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
		switch (snd_pcm_format_physical_width(i)) {
		case 8:
		case 16:
		case 32:
			omap_pcm_hardware.formats |= (1LL << i);
			break;
		default:
			break;
		}
	}
}
コード例 #18
0
static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock(
	struct snd_pcm_hw_params *params,
	struct snd_soc_dai *cpu_dai)
{
	struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
	struct ssc_device *ssc = ssc_p->ssc;
	struct ssc_clock_data cd;
	unsigned int rate, width_bits, channels;
	unsigned int bitrate, ssc_div;
	unsigned actual_rate;


	/*
	 * Figure out required bitrate
	 */
	rate = params_rate(params);
	channels = params_channels(params);
	width_bits = snd_pcm_format_physical_width(params_format(params));
	bitrate = rate * width_bits * channels;


	/*
	 * Figure out required SSC divider and period for required bitrate
	 */
	cd.ssc_rate = clk_get_rate(ssc->clk);
	ssc_div = cd.ssc_rate / bitrate;
	cd.cmr_div = ssc_div / 2;
	if (ssc_div & 1) {
		/* round cmr_div up */
		cd.cmr_div++;
	}
	cd.period = width_bits - 1;


	/*
	 * Find actual rate, compare to requested rate
	 */
	actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1));
	pr_debug("playpaq_wm8510: Request rate = %u, actual rate = %u\n",
		 rate, actual_rate);


	return cd;
}
コード例 #19
0
ファイル: pcm.c プロジェクト: 543872407/Linux_SourceCode
int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area,
		      snd_pcm_uframes_t dst_offset,
		      const snd_pcm_channel_area_t *src_area,
		      snd_pcm_uframes_t src_offset,
		      unsigned int samples, snd_pcm_format_t format)
{
	const char *src;
	char *dst;
	int width;
	int src_step, dst_step;

	if (!dst_area->addr)
		return 0;
	if (dst_area == src_area && dst_offset == src_offset)
		return 0;
	if (!src_area->addr)
		return snd_pcm_area_silence(dst_area, dst_offset, samples,
					    format);
	width = snd_pcm_format_physical_width(format);
	if (width < 8)
		return area_copy_4bit(dst_area, dst_offset,
				      src_area, src_offset,
				      samples, format);
	src = snd_pcm_channel_area_addr(src_area, src_offset);
	dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
	if (src_area->step == (unsigned int) width &&
	    dst_area->step == (unsigned int) width) {
		memcpy(dst, src, samples * width / 8);
		return 0;
	}
	src_step = src_area->step / 8;
	dst_step = dst_area->step / 8;
	width /= 8;
	while (samples-- > 0) {
		memcpy(dst, src, width);
		src += src_step;
		dst += dst_step;
	}
	return 0;
}
コード例 #20
0
ファイル: pcm.c プロジェクト: 543872407/Linux_SourceCode
int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas,
		       snd_pcm_uframes_t dst_offset,
		       const snd_pcm_channel_area_t *src_areas,
		       snd_pcm_uframes_t src_offset,
		       unsigned int channels, snd_pcm_uframes_t frames,
		       snd_pcm_format_t format)
{
	int width;
	if (!channels)
		return -EINVAL;
	if (!frames)
		return -EINVAL;
	width = snd_pcm_format_physical_width(format);
	while (channels > 0) {
		snd_pcm_area_copy(dst_areas, dst_offset,
				  src_areas, src_offset,
				  frames, format);
		src_areas++;
		dst_areas++;
		channels--;
	}
	return 0;
}
コード例 #21
0
// returns 1 if successful
// enc: 0 for PCM, 1 for ULAW, 2 for ALAW (see DirectAudio.h)
int getFormatFromAlsaFormat(snd_pcm_format_t alsaFormat,
                            int* sampleSizeInBytes, int* significantBits,
                            int* isSigned, int* isBigEndian, int* enc) {

    *sampleSizeInBytes = (snd_pcm_format_physical_width(alsaFormat) + 7) / 8;
    *significantBits = snd_pcm_format_width(alsaFormat);

    // defaults
    *enc = 0; // PCM
    *isSigned = (snd_pcm_format_signed(alsaFormat) > 0);
    *isBigEndian = (snd_pcm_format_big_endian(alsaFormat) > 0);

    // non-PCM formats
    if (alsaFormat == SND_PCM_FORMAT_MU_LAW) { // Mu-Law
        *sampleSizeInBytes = 8; *enc = 1; *significantBits = *sampleSizeInBytes;
    }
    else if (alsaFormat == SND_PCM_FORMAT_A_LAW) {     // A-Law
        *sampleSizeInBytes = 8; *enc = 2; *significantBits = *sampleSizeInBytes;
    }
    else if (snd_pcm_format_linear(alsaFormat) < 1) {
        return 0;
    }
    return (*sampleSizeInBytes > 0);
}
コード例 #22
0
/*
 * Set the SSP audio DMA parameters and sample size.
 * Can be called multiple times by oss emulation.
 */
static int pxa3xx_ssp_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params, struct snd_soc_dai * dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
	struct ssp_device *ssp = cpu_dai->private_data;
	struct pxa3xx_pcm_dma_params *pcm;
	u32 sscr0, sspsp;
	u32 width;

	pcm = kmalloc(sizeof(struct pxa3xx_pcm_dma_params), GFP_KERNEL);
	if (pcm == NULL)
		return -ENOMEM;

	/* bit size */
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
		sscr0 |= SSCR0_DataSize(16);
		__raw_writel(sscr0, ssp->mmio_base + SSCR0);

		if ((sscr0 & SSCR0_FPCKE ) || (sscr0 & SSCR0_EDSS))
			width = DCMD_WIDTH4;
		else
			width = DCMD_WIDTH2;

		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
		sscr0 |= SSCR0_EDSS | SSCR0_DataSize(16);
		__raw_writel(sscr0, ssp->mmio_base + SSCR0);

		width = DCMD_WIDTH4;

		break;
	default:
		return -EINVAL;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		pcm->name = ssp_names[cpu_dai->id][0];
		pcm->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
		pcm->drcmr = &DRCMR(ssp->drcmr_tx);
		pcm->dev_addr	= ssp->phys_base + SSDR;
	} else {
		pcm->name = ssp_names[cpu_dai->id][1];
		pcm->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC;
		pcm->drcmr = &DRCMR(ssp->drcmr_rx);
		pcm->dev_addr	= ssp->phys_base + SSDR;
	}

	pcm->dcmd |= DCMD_BURST16 | width;

	kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));

	snd_soc_dai_set_dma_data(cpu_dai, substream, pcm);

	if (ssp_clk[cpu_dai->id].dai_fmt == SND_SOC_DAIFMT_I2S) {
		int sfrmwidth =
			snd_pcm_format_physical_width(params_format(params));
		sspsp = __raw_readl(ssp->mmio_base + SSPSP);
		sspsp |= SSPSP_SFRMWDTH(sfrmwidth);
		__raw_writel(sspsp, ssp->mmio_base + SSPSP);
	}

	return 0;
}
コード例 #23
0
ファイル: ai_alsa1x.c プロジェクト: ArcherSeven/mpv
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;
}
コード例 #24
0
ファイル: play.c プロジェクト: hishamhm/protosampler
static void set_params(void)
{
	snd_pcm_hw_params_t *params;
	snd_pcm_sw_params_t *swparams;
	snd_pcm_uframes_t buffer_size;
	int err;
	size_t n;
	snd_pcm_uframes_t xfer_align;
	unsigned int rate;
	snd_pcm_uframes_t start_threshold, stop_threshold;
	snd_pcm_hw_params_alloca(&params);
	snd_pcm_sw_params_alloca(&swparams);
	err = snd_pcm_hw_params_any(handle, params);
	if (err < 0) {
		error(_("Broken configuration for this PCM: no configurations available"));
		exit(EXIT_FAILURE);
	}
	err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
	if (err < 0) {
		error(_("Access type not available"));
		exit(EXIT_FAILURE);
	}
	err = snd_pcm_hw_params_set_format(handle, params, hwparams.format);
	if (err < 0) {
		error(_("Sample format non available"));
		exit(EXIT_FAILURE);
	}
	err = snd_pcm_hw_params_set_channels(handle, params, hwparams.channels);
	if (err < 0) {
		error(_("Channels count non available"));
		exit(EXIT_FAILURE);
	}

#if 0
	err = snd_pcm_hw_params_set_periods_min(handle, params, 2);
	assert(err >= 0);
#endif
	rate = hwparams.rate;
	err = snd_pcm_hw_params_set_rate_near(handle, params, &hwparams.rate, 0);
	assert(err >= 0);
	if ((float)rate * 1.05 < hwparams.rate || (float)rate * 0.95 > hwparams.rate) {
		if (!quiet_mode) {
			char plugex[64];
			const char *pcmname = snd_pcm_name(handle);
			fprintf(stderr, _("Warning: rate is not accurate (requested = %iHz, got = %iHz)\n"), rate, hwparams.rate);
			if (! pcmname || strchr(snd_pcm_name(handle), ':'))
				*plugex = 0;
			else
				snprintf(plugex, sizeof(plugex), "(-Dplug:%s)",
					 snd_pcm_name(handle));
			fprintf(stderr, _("         please, try the plug plugin %s\n"),
				plugex);
		}
	}
	rate = hwparams.rate;
	if (buffer_time == 0 && buffer_frames == 0) {
		err = snd_pcm_hw_params_get_buffer_time_max(params,
							    &buffer_time, 0);
		assert(err >= 0);
		if (buffer_time > 500000)
			buffer_time = 500000;
	}
	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(handle, params,
							     &period_time, 0);
	else
		err = snd_pcm_hw_params_set_period_size_near(handle, params,
							     &period_frames, 0);
	assert(err >= 0);
	if (buffer_time > 0) {
		err = snd_pcm_hw_params_set_buffer_time_near(handle, params,
							     &buffer_time, 0);
	} else {
		err = snd_pcm_hw_params_set_buffer_size_near(handle, params,
							     &buffer_frames);
	}
	assert(err >= 0);
	err = snd_pcm_hw_params(handle, params);
	if (err < 0) {
		error(_("Unable to install hw params:"));
		snd_pcm_hw_params_dump(params, log);
		exit(EXIT_FAILURE);
	}
	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) {
		error(_("Can't use period equal to buffer size (%lu == %lu)"),
		      chunk_size, buffer_size);
		exit(EXIT_FAILURE);
	}
	snd_pcm_sw_params_current(handle, swparams);
	err = snd_pcm_sw_params_get_xfer_align(swparams, &xfer_align);
	if (err < 0) {
		error(_("Unable to obtain xfer align\n"));
		exit(EXIT_FAILURE);
	}
	if (sleep_min)
		xfer_align = 1;
	err = snd_pcm_sw_params_set_sleep_min(handle, swparams,
					      sleep_min);
	assert(err >= 0);
	if (avail_min < 0)
		n = chunk_size;
	else
		n = (double) rate * avail_min / 1000000;
	err = snd_pcm_sw_params_set_avail_min(handle, swparams, n);

	// round up to closest transfer boundary
	n = (buffer_size / xfer_align) * xfer_align;
	start_threshold = n;
	if (start_threshold < 1)
		start_threshold = 1;
	if (start_threshold > n)
		start_threshold = n;
	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
	assert(err >= 0);
	stop_threshold = buffer_size;
	err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
	assert(err >= 0);

	err = snd_pcm_sw_params_set_xfer_align(handle, swparams, xfer_align);
	assert(err >= 0);

	if (snd_pcm_sw_params(handle, swparams) < 0) {
		error(_("unable to install sw params:"));
		snd_pcm_sw_params_dump(swparams, log);
		exit(EXIT_FAILURE);
	}

	bits_per_sample = snd_pcm_format_physical_width(hwparams.format);
	bits_per_frame = bits_per_sample * hwparams.channels;
	chunk_bytes = chunk_size * bits_per_frame / 8;
	audiobuf = realloc(audiobuf, chunk_bytes);
	if (audiobuf == NULL) {
		error(_("not enough memory"));
		exit(EXIT_FAILURE);
	}
	// fprintf(stderr, "real chunk_size = %i, frags = %i, total = %i\n", chunk_size, setup.buf.block.frags, setup.buf.block.frags * chunk_size);
}
コード例 #25
0
ファイル: pcm_oss.c プロジェクト: Boshin/workspace
	    tmp > io->rate * 1.01 || tmp < io->rate * 0.99) {
		perror("SNDCTL_DSP_SPEED");
		return -EINVAL;
	}
	return 0;
}

static int oss_hw_params(snd_pcm_ioplug_t *io,
			 snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED)
{
	snd_pcm_oss_t *oss = io->private_data;
	int i, tmp, err;
	unsigned int period_bytes;
	long oflags, flags;

	oss->frame_bytes = (snd_pcm_format_physical_width(io->format) * io->channels) / 8;
	switch (io->format) {
	case SND_PCM_FORMAT_U8:
		oss->format = AFMT_U8;
		break;
	case SND_PCM_FORMAT_S16_LE:
		oss->format = AFMT_S16_LE;
		break;
	case SND_PCM_FORMAT_S16_BE:
		oss->format = AFMT_S16_BE;
		break;
	default:
		fprintf(stderr, "*** OSS: unsupported format %s\n", snd_pcm_format_name(io->format));
		return -EINVAL;
	}
	period_bytes = io->period_size * oss->frame_bytes;
コード例 #26
0
ファイル: aplaypop.c プロジェクト: vovcat/xcrutchd
static int aplaypop_open(void)
{
    int err;
    snd_pcm_t *handle;

    if (pcm_handle)
        return 0;

    snd_pcm_info_t *info;
    snd_pcm_info_alloca(&info);

    snd_output_t *log;
    err = snd_output_stdio_attach(&log, stderr, 0);
    assert(err == 0);

    err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_open(): %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    err = snd_pcm_nonblock(handle, 0);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_nonblock(): %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    err = snd_pcm_info(handle, info);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_info(): %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }

    // DOESN'T WORK!
    err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE,
        SND_PCM_ACCESS_RW_INTERLEAVED, CHANNELS, RATE, 1, 50000);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_set_params(): %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }

    // RIGHT WAY:
    snd_pcm_hw_params_t *hwparams;
    snd_pcm_sw_params_t *swparams;

    snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
    unsigned int channels = CHANNELS;
    unsigned int rate = RATE;

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

    err = snd_pcm_hw_params_any(handle, hwparams);
    if (err != 0) {
        fprintf(stderr, "Broken configuration for this PCM: %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_hw_params_set_access(): %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    err = snd_pcm_hw_params_set_format(handle, hwparams, format);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_hw_params_set_format(): %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    err = snd_pcm_hw_params_set_channels(handle, hwparams, channels);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_hw_params_set_channels(): %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
    err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, 0);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_hw_params_set_rate_near(): %s\n", snd_strerror(err));
        exit(EXIT_FAILURE);
    }
/*
    unsigned buffer_time = 0;
    snd_pcm_uframes_t buffer_frames = 0;

    if (buffer_time == 0 && buffer_frames == 0) {
        err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &buffer_time, 0);
        assert(err == 0);
        if (buffer_time > 500000)
            buffer_time = 500000;
    }

    unsigned period_time = 0;
    snd_pcm_uframes_t period_frames = 0;

    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(handle, hwparams, &period_time, 0);
    else
        err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_frames, 0);
    assert(err == 0);

    if (buffer_time > 0)
        err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, 0);
    else
        err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_frames);
    assert(err == 0);

    int monotonic = snd_pcm_hw_params_is_monotonic(hwparams);
    int can_pause = snd_pcm_hw_params_can_pause(hwparams);
*/
    err = snd_pcm_hw_params(handle, hwparams);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_hw_params(): %s\n", snd_strerror(err));
        snd_pcm_hw_params_dump(hwparams, log);
        exit(EXIT_FAILURE);
    }
    snd_pcm_uframes_t chunk_size = 0;
    snd_pcm_hw_params_get_period_size(hwparams, &chunk_size, 0);
    snd_pcm_uframes_t buffer_size;
    snd_pcm_hw_params_get_buffer_size(hwparams, &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);
    }
    snd_pcm_sw_params_current(handle, swparams);

    err = snd_pcm_sw_params_set_avail_min(handle, swparams, chunk_size);
    assert(err == 0);

    /* round up to closest transfer boundary */
    int start_delay = 0;
    snd_pcm_uframes_t start_threshold;
    if (start_delay <= 0)
        start_threshold = buffer_size + (double) rate * start_delay / 1000000;
    else
        start_threshold = (double) rate * start_delay / 1000000;
    start_threshold = start_threshold < 1 ? 1 : start_threshold > buffer_size ? buffer_size : start_threshold;
    err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
    assert(err == 0);

    int stop_delay = 0;
    snd_pcm_uframes_t stop_threshold;
    if (stop_delay <= 0)
        stop_threshold = buffer_size + (double) rate * stop_delay / 1000000;
    else
        stop_threshold = (double) rate * stop_delay / 1000000;
    err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
    assert(err == 0);

    err = snd_pcm_sw_params(handle, swparams);
    if (err != 0) {
        fprintf(stderr, "snd_pcm_sw_params(): %s\n", snd_strerror(err));
        snd_pcm_sw_params_dump(swparams, log);
        exit(EXIT_FAILURE);
    }
    // END OF THE RIGHT WAY

//  snd_pcm_dump(handle, log);

    size_t bits_per_sample = snd_pcm_format_physical_width(format);
    size_t bits_per_frame = bits_per_sample * channels;
    size_t chunk_bytes = chunk_size * bits_per_frame / 8;
    //audiobuf = realloc(audiobuf, chunk_bytes);

    fprintf(stderr, "%s: %s, Rate %d Hz, Channels=%u\n",
        snd_pcm_format_name(format), snd_pcm_format_description(format),
        rate, channels);
    fprintf(stderr, "  bits_per_sample=%u, bits_per_frame=%u, chunk_bytes=%u\n",
        bits_per_sample, bits_per_frame, chunk_bytes);

    frame_bytes = bits_per_frame / 8;
    pcm_handle = handle;
    return 0;
}
コード例 #27
0
ファイル: ga-alsa.cpp プロジェクト: Ljinod/gaminganywhere
int
ga_alsa_set_param(struct Xcap_alsa_param *param) {
	snd_pcm_hw_params_t *hwparams = NULL;
	snd_pcm_sw_params_t *swparams = NULL;
	size_t bits_per_sample;
	unsigned int rate;
	unsigned int buffer_time = 500000;	// in the unit of microsecond
	unsigned int period_time = 125000;	// = buffer_time/4;
	int monotonic = 0;
	snd_pcm_uframes_t start_threshold, stop_threshold;
	int err;
	//
	snd_pcm_hw_params_alloca(&hwparams);
	snd_pcm_sw_params_alloca(&swparams);
	if((err = snd_pcm_hw_params_any(param->handle, hwparams)) < 0) {
		ga_error("ALSA: set_param - no configurations available\n");
		return -1;
	}
	if((err = snd_pcm_hw_params_set_access(param->handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
		ga_error("ALSA: set_param - access type (interleaved) not available\n");
		return -1;
	}
	if((err = snd_pcm_hw_params_set_format(param->handle, hwparams, param->format)) < 0) {
		ga_error("ALSA: set_param - unsupported sample format.\n");
		return -1;
	}
	if((err = snd_pcm_hw_params_set_channels(param->handle, hwparams, param->channels)) < 0) {
		ga_error("ALSA: set_param - channles count not available\n");
		return -1;
	}
	rate = param->samplerate;
	if((err = snd_pcm_hw_params_set_rate_near(param->handle, hwparams, &rate, 0)) < 0) {
		ga_error("ALSA: set_param - set rate failed.\n");
		return -1;
	}
	if((double)param->samplerate*1.05 < rate || (double)param->samplerate*0.95 > rate) {
		ga_error("ALSA: set_param/warning - inaccurate rate (req=%iHz, got=%iHz)\n", param->samplerate, rate);
	}
	//
	period_time = buffer_time/4;
	if((err = snd_pcm_hw_params_set_period_time_near(param->handle, hwparams, &period_time, 0)) < 0) {
		ga_error("ALSA: set_param - set period time failed.\n");
		return -1;
	}
	if((err = snd_pcm_hw_params_set_buffer_time_near(param->handle, hwparams, &buffer_time, 0)) < 0) {
		ga_error("ALSA: set_param - set buffer time failed.\n");
		return -1;
	}
	//
	monotonic = snd_pcm_hw_params_is_monotonic(hwparams);
	if((err = snd_pcm_hw_params(param->handle, hwparams)) < 0) {
		ga_error("ALSA: set_param - unable to install hw params:");
		snd_pcm_hw_params_dump(hwparams, sndlog);
		return -1;
	}
	snd_pcm_hw_params_get_period_size(hwparams, &param->chunk_size, 0);
	snd_pcm_hw_params_get_buffer_size(hwparams, &param->buffer_size);
	if(param->chunk_size == param->buffer_size) {
		ga_error("ALSA: set_param - cannot use period equal to buffer size (%lu==%lu)\n",
			param->chunk_size, param->buffer_size);
		return -1;
	}
	//
	snd_pcm_sw_params_current(param->handle, swparams);
	err = snd_pcm_sw_params_set_avail_min(param->handle, swparams, param->chunk_size);
	// start_delay = 1 for capture
	start_threshold = (double) param->samplerate * /*start_delay=*/ 1 / 1000000;
	if(start_threshold < 1)				start_threshold = 1;
	if(start_threshold > param->buffer_size)	start_threshold = param->buffer_size;
	if((err = snd_pcm_sw_params_set_start_threshold(param->handle, swparams, start_threshold)) < 0) {
		ga_error("ALSA: set_param - set start threshold failed.\n");
		return -1;
	}
	// stop_delay = 0
	stop_threshold = param->buffer_size;
	if((err = snd_pcm_sw_params_set_stop_threshold(param->handle, swparams, stop_threshold)) < 0) {
		ga_error("ALSA: set_param - set stop threshold failed.\n");
		return -1;
	}
	//
	if(snd_pcm_sw_params(param->handle, swparams) < 0) {
		ga_error("ALSA: set_param - unable to install sw params:");
		snd_pcm_sw_params_dump(swparams, sndlog);
		return -1;
	}

	bits_per_sample = snd_pcm_format_physical_width(param->format);
	if(param->bits_per_sample != bits_per_sample) {
		ga_error("ALSA: set_param - BPS/HW configuration mismatched %d != %d)\n",
			param->bits_per_sample, bits_per_sample);
	}
	param->bits_per_frame = param->bits_per_sample * param->channels;
	param->chunk_bytes = param->chunk_size * param->bits_per_frame / 8;

	return 0;
}
コード例 #28
0
ファイル: u_uac1.c プロジェクト: Leoyzen/Charm-Eye
static int capture_prepare_params(struct gaudio_snd_dev *snd)
{
	struct snd_pcm_substream *substream = snd->substream;
	struct snd_pcm_runtime   *runtime = substream->runtime;
	struct snd_pcm_hw_params *params;
	struct snd_pcm_sw_params *swparams;
	unsigned long period_size;
	unsigned long buffer_size;
	snd_pcm_sframes_t result = 0;

	snd->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
	snd->format = SNDRV_PCM_FORMAT_S16_LE;
	snd->channels = 1;
	snd->rate = 8000;

	params = kzalloc(sizeof(*params), GFP_KERNEL);
	if (!params) {
		pr_err("Failed to allocate hw params");
		return -ENOMEM;
	}

	_snd_pcm_hw_params_any(params);
	_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS,
			snd->access, 0);
	_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT,
			snd->format, 0);
	_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS,
			snd->channels, 0);
	_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE,
			snd->rate, 0);

	result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
	if (result < 0)
		pr_err("SNDRV_PCM_IOCTL_DROP failed: %d\n", (int)result);

	result = snd_pcm_kernel_ioctl(substream,
			SNDRV_PCM_IOCTL_HW_PARAMS, params);
	if (result < 0) {
		pr_err("SNDRV_PCM_IOCTL_HW_PARAMS failed: %d\n", (int)result);
		kfree(params);
		return result;
	}

	result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE,
					NULL);
	if (result < 0)
		pr_err("Preparing capture failed: %d\n", (int)result);

	
	snd->access = params_access(params);
	snd->format = params_format(params);
	snd->channels = params_channels(params);
	snd->rate = params_rate(params);

	runtime->frame_bits = snd_pcm_format_physical_width(runtime->format);

	swparams = kzalloc(sizeof(*swparams), GFP_KERNEL);
	if (!swparams) {
		pr_err("Failed to allocate sw params");
		kfree(params);
		return -ENOMEM;
	}

	buffer_size = pcm_buffer_size(params);
	period_size = pcm_period_size(params);
	swparams->avail_min = period_size/2;
	swparams->xfer_align = period_size/2;

	kfree(params);

	swparams->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
	swparams->period_step = 1;
	swparams->start_threshold = 1;
	swparams->stop_threshold = INT_MAX;
	swparams->silence_size = 0;
	swparams->silence_threshold = 0;

	result = snd_pcm_kernel_ioctl(substream,
			SNDRV_PCM_IOCTL_SW_PARAMS, swparams);
	if (result < 0)
		pr_err("SNDRV_PCM_IOCTL_SW_PARAMS failed: %d\n", (int)result);

	kfree(swparams);

	pr_debug("capture params: access %x, format %x, channels %d, rate %d\n",
		snd->access, snd->format, snd->channels, snd->rate);

	return result;
}
コード例 #29
0
ファイル: wav_play_record.c プロジェクト: hanlui/bat
static int set_snd_pcm_params(struct bat *bat, struct snd_pcm_container *sndpcm)
{
    snd_pcm_format_t format;
    snd_pcm_hw_params_t *params;
    unsigned int buffer_time = 0;
    unsigned int period_time = 0;
    unsigned int rate;
    int err;
    const char *device_name = snd_pcm_name(sndpcm->handle);

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

    /* Fill it in with default values. */
    err = snd_pcm_hw_params_any(sndpcm->handle, params);
    if (err < 0) {
        loge(E_SETDEV S_DEFAULT, "%s: %s(%d)",
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    /* Set access mode */
    err = snd_pcm_hw_params_set_access(sndpcm->handle, params,
                                       SND_PCM_ACCESS_RW_INTERLEAVED);
    if (err < 0) {
        loge(E_SETDEV S_ACCESS, "%s: %s(%d)",
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    /* Set format */
    switch (bat->sample_size) {
    case 1:
        format = SND_PCM_FORMAT_S8;
        break;
    case 2:
        format = SND_PCM_FORMAT_S16_LE;
        break;
    case 3:
        format = SND_PCM_FORMAT_S24_3LE;
        break;
    case 4:
        format = SND_PCM_FORMAT_S32_LE;
        break;
    default:
        loge(E_PARAMS S_PCMFORMAT, "size=%d", bat->sample_size);
        goto fail_exit;
    }
    err = snd_pcm_hw_params_set_format(sndpcm->handle, params, format);
    if (err < 0) {
        loge(E_SETDEV S_PCMFORMAT, "%d %s: %s(%d)",
             format,
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    /* Set channels */
    err = snd_pcm_hw_params_set_channels(sndpcm->handle,
                                         params, bat->channels);
    if (err < 0) {
        loge(E_SETDEV S_CHANNELS, "%d %s: %s(%d)",
             bat->channels,
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    /* Set sampling rate */
    rate = bat->rate;
    err = snd_pcm_hw_params_set_rate_near(sndpcm->handle,
                                          params, &bat->rate,
                                          0);
    if (err < 0) {
        loge(E_SETDEV S_SAMPLERATE, "%d %s: %s(%d)",
             bat->rate,
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }
    if ((float) rate * 1.05 < bat->rate
            || (float) rate * 0.95 > bat->rate) {
        loge(E_PARAMS S_SAMPLERATE, "requested %dHz, got %dHz",
             rate, bat->rate);
        goto fail_exit;
    }

    if (snd_pcm_hw_params_get_buffer_time_max(params,
            &buffer_time, 0) < 0) {
        loge(E_GETDEV S_BUFFERTIME, "%d %s: %s(%d)",
             buffer_time,
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    if (buffer_time > 500000)
        buffer_time = 500000;
    /* Was 4, changed to 8 to remove reduce capture overrun */
    period_time = buffer_time / 8;

    /* Set buffer time and period time */
    err = snd_pcm_hw_params_set_buffer_time_near(sndpcm->handle, params,
            &buffer_time, 0);
    if (err < 0) {
        loge(E_SETDEV S_BUFFERTIME, "%d %s: %s(%d)",
             buffer_time,
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    err = snd_pcm_hw_params_set_period_time_near(sndpcm->handle, params,
            &period_time, 0);
    if (err < 0) {
        loge(E_SETDEV S_PERIODTIME, "%d %s: %s(%d)",
             period_time,
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    /* Write the parameters to the driver */
    if (snd_pcm_hw_params(sndpcm->handle, params) < 0) {
        loge(E_SETDEV S_HWPARAMS, "%s: %s(%d)",
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    err = snd_pcm_hw_params_get_period_size(params,
                                            &sndpcm->period_size, 0);
    if (err < 0) {
        loge(E_GETDEV S_PERIODSIZE, "%zd %s: %s(%d)",
             sndpcm->period_size,
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    err = snd_pcm_hw_params_get_buffer_size(params, &sndpcm->buffer_size);
    if (err < 0) {
        loge(E_GETDEV S_BUFFERSIZE, "%zd %s: %s(%d)",
             sndpcm->buffer_size,
             device_name, snd_strerror(err), err);
        goto fail_exit;
    }

    if (sndpcm->period_size == sndpcm->buffer_size) {
        loge(E_PARAMS, "can't use period equal to buffer size (%zd)",
             sndpcm->period_size);
        goto fail_exit;
    }

    err = snd_pcm_format_physical_width(format);
    if (err < 0) {
        loge(E_PARAMS, "snd_pcm_format_physical_width: %d", err);
        goto fail_exit;
    }
    sndpcm->sample_bits = err;

    sndpcm->frame_bits = sndpcm->sample_bits * bat->channels;

    /* Calculate the period bytes */
    sndpcm->period_bytes = sndpcm->period_size * sndpcm->frame_bits / 8;
    sndpcm->buffer = (char *) malloc(sndpcm->period_bytes);
    if (sndpcm->buffer == NULL) {
        loge(E_MALLOC, "size=%zd", sndpcm->period_bytes);
        goto fail_exit;
    }

    return 0;

fail_exit:
    return -1;
}
コード例 #30
0
ファイル: arecord.c プロジェクト: JordanBlocher/record
/* write a WAVE-header */
static void begin_wave(int fd, size_t cnt)
{
	WaveHeader h;
	WaveFmtBody f;
	WaveChunkHeader cf, cd;
	int bits;
	u_int tmp;
	u_short tmp2;

	/* WAVE cannot handle greater than 32bit (signed?) int */
	if (cnt == (size_t)-2)
		cnt = 0x7fffff00;

	bits = 8;
	switch ((unsigned long) hwparams.format) {
	case SND_PCM_FORMAT_U8:
		bits = 8;
		break;
	case SND_PCM_FORMAT_S16_LE:
		bits = 16;
		break;
	case SND_PCM_FORMAT_S32_LE:
        case SND_PCM_FORMAT_FLOAT_LE:
		bits = 32;
		break;
	case SND_PCM_FORMAT_S24_LE:
	case SND_PCM_FORMAT_S24_3LE:
		bits = 24;
		break;
	default:
		error(_("Wave doesn't support %s format..."), snd_pcm_format_name(hwparams.format));
		exit(EXIT_FAILURE);
	}
	h.magic = WAV_RIFF;
	tmp = cnt + sizeof(WaveHeader) + sizeof(WaveChunkHeader) + sizeof(WaveFmtBody) + sizeof(WaveChunkHeader) - 8;
	h.length = LE_INT(tmp);
	h.type = WAV_WAVE;

	cf.type = WAV_FMT;
	cf.length = LE_INT(16);

        if (hwparams.format == SND_PCM_FORMAT_FLOAT_LE)
                f.format = LE_SHORT(WAV_FMT_IEEE_FLOAT);
        else
                f.format = LE_SHORT(WAV_FMT_PCM);
	f.channels = LE_SHORT(hwparams.channels);
	f.sample_fq = LE_INT(hwparams.rate);
#if 0
	tmp2 = (samplesize == 8) ? 1 : 2;
	f.byte_p_spl = LE_SHORT(tmp2);
	tmp = dsp_speed * hwparams.channels * (u_int) tmp2;
#else
	tmp2 = hwparams.channels * snd_pcm_format_physical_width(hwparams.format) / 8;
	f.byte_p_spl = LE_SHORT(tmp2);
	tmp = (u_int) tmp2 * hwparams.rate;
#endif
	f.byte_p_sec = LE_INT(tmp);
	f.bit_p_spl = LE_SHORT(bits);

	cd.type = WAV_DATA;
	cd.length = LE_INT(cnt);

	if (write(fd, &h, sizeof(WaveHeader)) != sizeof(WaveHeader) ||
	    write(fd, &cf, sizeof(WaveChunkHeader)) != sizeof(WaveChunkHeader) ||
	    write(fd, &f, sizeof(WaveFmtBody)) != sizeof(WaveFmtBody) ||
	    write(fd, &cd, sizeof(WaveChunkHeader)) != sizeof(WaveChunkHeader)) {
		error(_("write error"));
		exit(EXIT_FAILURE);
	}
}