コード例 #1
0
/*
 * return the highest sample rate supported by audio device |dev|.
 */
static int
find_highest_samplerate(int dev)
{
#if	HAVE_SYS_MIXER_H
    am_sample_rates_t *sr;
    int i, num, max_rate;

    for (num = 16; num < 1024; num *= 2) {
	sr = malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(num));
	if (!sr)
	    return 0;
	sr->type = AUDIO_PLAY;
	sr->flags = 0;
	sr->num_samp_rates = num;
	if (ioctl(dev, AUDIO_MIXER_GET_SAMPLE_RATES, sr)) {
	    free(sr);
	    return 0;
	}
	if (sr->num_samp_rates <= num)
	    break;
	free(sr);
    }

    if (sr->flags & MIXER_SR_LIMITS) {
	/*
	 * HW can playback any rate between 
	 * sr->samp_rates[0] .. sr->samp_rates[1]
	 */
	max_rate = sr->samp_rates[1];
    } else {
	/* HW supports fixed sample rates only */
	max_rate = 0;
	for (i = 0; i < sr->num_samp_rates; i++) {
	    if (sr->samp_rates[i] > max_rate)
		max_rate = sr->samp_rates[i];
	}
    }
    free(sr);
    return max_rate;

#else
    return 44100;	/* should be supported even on old ISA SB cards */
#endif
}
コード例 #2
0
/* 
 * match the requested sample rate |sample_rate| against the
 * sample rates supported by the audio device |dev|.  Return
 * a supported sample rate,  it that sample rate is close to
 * (< 1% difference) the requested rate; return 0 otherwise.
 */
static int
find_close_samplerate_match(int dev, int sample_rate)
{
#if	HAVE_SYS_MIXER_H
    am_sample_rates_t *sr;
    int i, num, err, best_err, best_rate;

    for (num = 16; num < 1024; num *= 2) {
	sr = malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(num));
	if (!sr)
	    return 0;
	sr->type = AUDIO_PLAY;
	sr->flags = 0;
	sr->num_samp_rates = num;
	if (ioctl(dev, AUDIO_MIXER_GET_SAMPLE_RATES, sr)) {
	    free(sr);
	    return 0;
	}
	if (sr->num_samp_rates <= num)
	    break;
	free(sr);
    }

    if (sr->flags & MIXER_SR_LIMITS) {
	/*
	 * HW can playback any rate between 
	 * sr->samp_rates[0] .. sr->samp_rates[1]
	 */
	free(sr);
	return 0;
    } else {
	/* HW supports fixed sample rates only */

	best_err = 65535;
	best_rate = 0;

	for (i = 0; i < sr->num_samp_rates; i++) {
	    err = abs(sr->samp_rates[i] - sample_rate);
	    if (err == 0) {
		/*
		 * exact supported sample rate match, no need to
		 * retry something else
		 */
		best_rate = 0;
		break;
	    }
	    if (err < best_err) {
		best_err = err;
		best_rate = sr->samp_rates[i];
	    }
	}

	free(sr);

	if (best_rate > 0 && 100*best_err < sample_rate) {
	    /* found a supported sample rate with <1% error? */
	    return best_rate;
	}
	return 0;
    }

#else
    int i, err;
    int audiocs_rates[] = {
	5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
	27420, 32000, 33075, 37800, 44100, 48000, 0
    };

    for (i = 0; audiocs_rates[i]; i++) {
	err = abs(audiocs_rates[i] - sample_rate);
	if (err == 0) {
	    /* 
	     * exact supported sample rate match, no need to
	     * retry something elise
	     */
	    return 0;
	}
	if (100*err < audiocs_rates[i]) {
	    /* <1% error? */
	    return audiocs_rates[i];
	}
    }

    return 0;
#endif
}
コード例 #3
0
void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
    int fd = -1;
    AudioDeviceDescription desc;
    am_sample_rates_t      *sr;
    /* hardcoded bits and channels */
    int bits[] = {8, 16}; 
    int bitsCount = 2;
    int channels[] = {1, 2}; 
    int channelsCount = 2;
    /* for querying sample rates */
    int err;
    int ch, b, s;

    TRACE2("DAUDIO_GetFormats, mixer %d, isSource=%d\n", mixerIndex, isSource);
    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
	fd = open(desc.pathctl, O_RDONLY);
    }
    if (fd < 0) {
	ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
	return;
    }

    /* get sample rates */
    sr = (am_sample_rates_t*) malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(MAX_SAMPLE_RATES));
    if (sr == NULL) {
	ERROR1("DAUDIO_GetFormats: out of memory for mixer %d\n", (int) mixerIndex);
	close(fd);
	return;
    }
    
    sr->num_samp_rates = MAX_SAMPLE_RATES;
    sr->type = isSource?AUDIO_PLAY:AUDIO_RECORD;
    sr->samp_rates[0] = -2;
    err = ioctl(fd, AUDIO_MIXER_GET_SAMPLE_RATES, sr);
    if (err < 0) {
	ERROR1("  DAUDIO_GetFormats: AUDIO_MIXER_GET_SAMPLE_RATES failed for mixer %d!\n", 
	       (int)mixerIndex);
	ERROR2(" -> num_sample_rates=%d sample_rates[0] = %d\n",
	       (int) sr->num_samp_rates,
	       (int) sr->samp_rates[0]);
	/* Some Solaris 8 drivers fail for get sample rates!
	 * Do as if we support all sample rates
	 */
	sr->flags = MIXER_SR_LIMITS;
    }
    if ((sr->flags & MIXER_SR_LIMITS)
	|| (sr->num_samp_rates > MAX_SAMPLE_RATES)) {
#ifdef USE_TRACE
	if ((sr->flags & MIXER_SR_LIMITS)) {
	    TRACE1("  DAUDIO_GetFormats: floating sample rate allowed by mixer %d\n", 
		   (int)mixerIndex);
	}
	if (sr->num_samp_rates > MAX_SAMPLE_RATES) {
	    TRACE2("  DAUDIO_GetFormats: more than %d formats. Use -1 for sample rates mixer %d\n", 
		   MAX_SAMPLE_RATES, (int)mixerIndex);
	}
#endif
	/*
	 * Fake it to have only one sample rate: -1
	 */
	sr->num_samp_rates = 1;
	sr->samp_rates[0] = -1;
    }
    close(fd);

    for (ch = 0; ch < channelsCount; ch++) {
	for (b = 0; b < bitsCount; b++) {
	    for (s = 0; s < sr->num_samp_rates; s++) {
		DAUDIO_AddAudioFormat(creator, 
				      bits[b], /* significant bits */
				      0, /* frameSize: let it be calculated */
				      channels[ch], 
				      (float) ((int) sr->samp_rates[s]),
				      DAUDIO_PCM, /* encoding - let's only do PCM */
				      (bits[b] > 8)?TRUE:TRUE, /* isSigned */
#if (X_WORD_ORDER == TRUE)
				      FALSE /* little endian */
#else
				      (bits[b] > 8)?TRUE:FALSE  /* big endian */
#endif
				      );
	    }
	}
    }
    free(sr);
}