Example #1
0
/* Set constraints for hw_params.  This lists the handled formats, sample rates,
 * access patters, and buffer/period sizes.  These are enforce in
 * snd_pcm_set_params(). */
static int set_hw_constraints(struct snd_pcm_cras *pcm_cras)
{
	static const unsigned int access_list[] = {
		SND_PCM_ACCESS_MMAP_INTERLEAVED,
		SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
		SND_PCM_ACCESS_RW_INTERLEAVED,
		SND_PCM_ACCESS_RW_NONINTERLEAVED
	};
	static const unsigned int format_list[] = {
		SND_PCM_FORMAT_U8,
		SND_PCM_FORMAT_S16_LE,
		SND_PCM_FORMAT_S24_LE,
		SND_PCM_FORMAT_S32_LE,
		SND_PCM_FORMAT_S24_3LE,
	};
	int rc;

	rc = snd_pcm_ioplug_set_param_list(&pcm_cras->io,
					   SND_PCM_IOPLUG_HW_ACCESS,
					   ARRAY_SIZE(access_list),
					   access_list);
	if (rc < 0)
		return rc;
	rc = snd_pcm_ioplug_set_param_list(&pcm_cras->io,
					   SND_PCM_IOPLUG_HW_FORMAT,
					   ARRAY_SIZE(format_list),
					   format_list);
	if (rc < 0)
		return rc;
	rc = snd_pcm_ioplug_set_param_minmax(&pcm_cras->io,
					     SND_PCM_IOPLUG_HW_CHANNELS,
					     1,
					     pcm_cras->channels);
	if (rc < 0)
		return rc;
	rc = snd_pcm_ioplug_set_param_minmax(&pcm_cras->io,
					    SND_PCM_IOPLUG_HW_RATE,
					    8000,
					    48000);
	if (rc < 0)
		return rc;
	rc = snd_pcm_ioplug_set_param_minmax(&pcm_cras->io,
					     SND_PCM_IOPLUG_HW_BUFFER_BYTES,
					     64,
					     2 * 1024 * 1024);
	if (rc < 0)
		return rc;
	rc = snd_pcm_ioplug_set_param_minmax(&pcm_cras->io,
					     SND_PCM_IOPLUG_HW_PERIOD_BYTES,
					     64,
					     2 * 1024 * 1024);
	if (rc < 0)
		return rc;
	rc = snd_pcm_ioplug_set_param_minmax(&pcm_cras->io,
					     SND_PCM_IOPLUG_HW_PERIODS,
					     1,
					     2048);
	return rc;
}
static int ste_iop_set_hw_constraint(ste_iop_t *ste_iop)
{
    unsigned int access_list[] = {
        SND_PCM_ACCESS_RW_INTERLEAVED
    };
    unsigned int format_list[] = {
        SND_PCM_FORMAT_S16_LE
    };

    int err;

    /* Set access constraint */
    err = snd_pcm_ioplug_set_param_list(&ste_iop->io, SND_PCM_IOPLUG_HW_ACCESS,
        ARRAY_SIZE(access_list), access_list);
    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to set access constraint: %s\n", snd_strerror(err));
        return err;
    }

    /* Set format constraint */
    err = snd_pcm_ioplug_set_param_list(&ste_iop->io, SND_PCM_IOPLUG_HW_FORMAT,
        ARRAY_SIZE(format_list), format_list);
    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to set access constraint: %s\n", snd_strerror(err));
        return err;
    }

    /* Set channels constraint */
    err = snd_pcm_ioplug_set_param_minmax(&ste_iop->io,
        SND_PCM_IOPLUG_HW_CHANNELS, STE_IOP_MIN_CHANNELS, STE_IOP_MAX_CHANNELS);
    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to set channels constraint: %s\n", snd_strerror(err));
        return err;
    }

    /* Set sample rate constraint */
    err = snd_pcm_ioplug_set_param_minmax(&ste_iop->io,
        SND_PCM_IOPLUG_HW_RATE, STE_IOP_MIN_RATE, STE_IOP_MAX_RATE);
    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to set rate constraint: %s\n", snd_strerror(err));
        return err;
    }

    /* Set period bytes constraint */
    err = snd_pcm_ioplug_set_param_minmax(&ste_iop->io,
        SND_PCM_IOPLUG_HW_PERIOD_BYTES,
        STE_IOP_MIN_PERIOD_BYTES, STE_IOP_MAX_PERIOD_BYTES);
    if (err < 0) {
        fprintf(stderr, "ST-Ericsson ALSA ADM I/O Plugin: Failed to set period bytes constraint: %s\n",
            snd_strerror(err));
        return err;
    }

    return 0;
}
Example #3
0
static int a2dp_constraint(snd_pcm_a2dp_t *a2dp)
{
	snd_pcm_ioplug_t *io = &a2dp->io;
	snd_pcm_access_t access_list[] = {
		SND_PCM_ACCESS_RW_INTERLEAVED,
		SND_PCM_ACCESS_MMAP_INTERLEAVED,
	};
	unsigned int format[2], channel[2], rate[2];
	int err;

	DBG("a2dp %p", a2dp);

	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS, 2, access_list);
	if (err < 0)
		return err;

	format[0] = SND_PCM_FORMAT_S16_LE;

	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT, 1, format);
	if (err < 0)
		return err;

	channel[0] = 1;
	channel[1] = 2;

	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_CHANNELS, 2, channel);
	if (err < 0)
		return err;

	rate[0] = 44100;
	rate[1] = 48000;

	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_RATE, 2, rate);
	if (err < 0)
		return err;

	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 8192, 8192);
	if (err < 0)
		return err;

	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 2, 2);
	if (err < 0)
		return err;

	return 0;
}
Example #4
0
// Alsa can convert about any format/channels/rate to any other rate
// However, since we added some code in the daemon to convert, why not do it ourselves!!!
// Moreover some player like aplay won't play a wav file if the device that do not natively support the requested format
// If you want alsa to do the conversion, just remove the value you want to see converted
static int a2dp_constraint(snd_pcm_a2dp_t * a2dp)
{
	snd_pcm_ioplug_t *io = &a2dp->io;
	#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
	snd_pcm_access_t access_list[] = { SND_PCM_ACCESS_RW_INTERLEAVED };
	unsigned int formats[] = { SND_PCM_FORMAT_U8, SND_PCM_FORMAT_S8, SND_PCM_FORMAT_S16_LE };
	unsigned int channels[] = { 1, 2 };
	unsigned int rates[] = { 8000, 11025, 22050, 32000, 44100, 48000 };
	int formats_nb = ARRAY_SIZE(formats);
	int channels_nb = ARRAY_SIZE(channels);
	int rates_nb = ARRAY_SIZE(rates);
	int rate_daemon = 0;
	int rate_prefered = 0;
	char srcfilename[512];
	int err;

	get_config_filename(srcfilename, sizeof(srcfilename));
	// Default is same as the daemon
	rate_daemon = read_config_int(srcfilename, "a2dpd", "rate", A2DPD_FRAME_RATE);
	// If a value is specified, use it
	rate_prefered = read_config_int(srcfilename, "a2dpd", "plugin-rate", rate_daemon);
	// If this value is not 0, alsa will convert to plugin-rate
	if(rate_prefered != 0) {
		// use defaults settings the rate specified + 16 bits stereo
		rates[0] = rate_prefered;
		rates_nb = 1;
		formats[0] = SND_PCM_FORMAT_S16_LE;
		formats_nb = 1;
		channels[0] = 2;
		channels_nb = 1;
	} else {
		// If this value is 0, the daemon will do most conversions
	}

	syslog(LOG_INFO, "[build %s %s] a2dp %p", __DATE__, __TIME__, a2dp);

	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS, ARRAY_SIZE(access_list), access_list);
	if (err < 0)
		return err;

	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT, formats_nb, formats);
	if (err < 0)
		return err;

	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_CHANNELS, channels_nb, channels);
	if (err < 0)
		return err;

	err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_RATE, rates_nb, rates);
	if (err < 0)
		return err;

	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 8192, 8192);
	if (err < 0)
		return err;

	err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 2, 2);
	if (err < 0)
		return err;

	return 0;
}