Beispiel #1
0
int audio_get_formats(struct audio_info_struct *ai)
{
    snd_pcm_hw_params_t *hw;
    unsigned int rate;
    int supported_formats, i;

    snd_pcm_hw_params_alloca(&hw);
    if (snd_pcm_hw_params_any(ai->handle, hw) < 0) {
        fprintf(stderr, "audio_get_formats(): no configuration available\n");
        return -1;
    }
    if (snd_pcm_hw_params_set_access(ai->handle, hw, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
        return -1;
    if (snd_pcm_hw_params_set_channels(ai->handle, hw, ai->channels) < 0)
        return 0;
    rate = ai->rate;
    if (snd_pcm_hw_params_set_rate_near(ai->handle, hw, &rate, NULL) < 0)
        return -1;
    if (!rates_match(ai->rate, rate))
        return 0;
    supported_formats = 0;
    for (i = 0; i < NUM_FORMATS; ++i) {
        if (snd_pcm_hw_params_test_format(ai->handle, hw, format_map[i].alsa) == 0)
            supported_formats |= format_map[i].mpg123;
    }
    return supported_formats;
}
Beispiel #2
0
static int get_formats_alsa(audio_output_t *ao)
{
	snd_pcm_t *pcm=(snd_pcm_t*)ao->userptr;
	snd_pcm_hw_params_t *hw;
	unsigned int rate;
	int supported_formats, i;

	snd_pcm_hw_params_alloca(&hw);
	if (snd_pcm_hw_params_any(pcm, hw) < 0) {
		if(!0) printf("get_formats_alsa(): no configuration available");
		return -1;
	}
	if (snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
		return -1;
	if (snd_pcm_hw_params_set_channels(pcm, hw, ao->channels) < 0)
		return 0;
	rate = ao->rate;
	if (snd_pcm_hw_params_set_rate_near(pcm, hw, &rate, NULL) < 0)
		return -1;
	if (!rates_match(ao->rate, rate))
		return 0;
	supported_formats = 0;
	for (i = 0; i < NUM_FORMATS; ++i) {
		if (snd_pcm_hw_params_test_format(pcm, hw, format_map[i].alsa) == 0)
			supported_formats |= format_map[i].mpg123;
	}
	return supported_formats;
}
Beispiel #3
0
static int initialize_device(struct audio_info_struct *ai)
{
    snd_pcm_hw_params_t *hw;
    int i;
    snd_pcm_format_t format;
    unsigned int rate;
    snd_pcm_uframes_t buffer_size;
    snd_pcm_uframes_t period_size;
    snd_pcm_sw_params_t *sw;
    snd_pcm_uframes_t boundary;

    snd_pcm_hw_params_alloca(&hw);
    if (snd_pcm_hw_params_any(ai->handle, hw) < 0) {
        fprintf(stderr, "initialize_device(): no configuration available\n");
        return -1;
    }
    if (snd_pcm_hw_params_set_access(ai->handle, hw, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
        fprintf(stderr, "initialize_device(): device does not support interleaved access\n");
        return -1;
    }
    format = SND_PCM_FORMAT_UNKNOWN;
    for (i = 0; i < NUM_FORMATS; ++i) {
        if (ai->format == format_map[i].mpg123) {
            format = format_map[i].alsa;
            break;
        }
    }
    if (format == SND_PCM_FORMAT_UNKNOWN) {
        fprintf(stderr, "initialize_device(): invalid sample format %d\n", ai->format);
        errno = EINVAL;
        return -1;
    }
    if (snd_pcm_hw_params_set_format(ai->handle, hw, format) < 0) {
        fprintf(stderr, "initialize_device(): cannot set format %s\n", snd_pcm_format_name(format));
        return -1;
    }
    if (snd_pcm_hw_params_set_channels(ai->handle, hw, ai->channels) < 0) {
        fprintf(stderr, "initialize_device(): cannot set %d channels\n", ai->channels);
        return -1;
    }
    rate = ai->rate;
    if (snd_pcm_hw_params_set_rate_near(ai->handle, hw, &rate, NULL) < 0) {
        fprintf(stderr, "initialize_device(): cannot set rate %u\n", rate);
        return -1;
    }
    if (!rates_match(ai->rate, rate)) {
        fprintf(stderr, "initialize_device(): rate %ld not available, using %u\n", ai->rate, rate);
        /* return -1; */
    }
    buffer_size = rate * BUFFER_LENGTH;
    if (snd_pcm_hw_params_set_buffer_size_near(ai->handle, hw, &buffer_size) < 0) {
        fprintf(stderr, "initialize_device(): cannot set buffer size\n");
        return -1;
    }
    period_size = buffer_size / 4;
    if (snd_pcm_hw_params_set_period_size_near(ai->handle, hw, &period_size, NULL) < 0) {
        fprintf(stderr, "initialize_device(): cannot set period size\n");
        return -1;
    }
    if (snd_pcm_hw_params(ai->handle, hw) < 0) {
        fprintf(stderr, "initialize_device(): cannot set hw params\n");
        return -1;
    }

    snd_pcm_sw_params_alloca(&sw);
    if (snd_pcm_sw_params_current(ai->handle, sw) < 0) {
        fprintf(stderr, "initialize_device(): cannot get sw params\n");
        return -1;
    }
    /* start playing after the first write */
    if (snd_pcm_sw_params_set_start_threshold(ai->handle, sw, 1) < 0) {
        fprintf(stderr, "initialize_device(): cannot set start threshold\n");
        return -1;
    }
    if (snd_pcm_sw_params_get_boundary(sw, &boundary) < 0) {
        fprintf(stderr, "initialize_device(): cannot get boundary\n");
        return -1;
    }
    /* never stop on underruns */
    if (snd_pcm_sw_params_set_stop_threshold(ai->handle, sw, boundary) < 0) {
        fprintf(stderr, "initialize_device(): cannot set stop threshold\n");
        return -1;
    }
    /* wake up on every interrupt */
    if (snd_pcm_sw_params_set_avail_min(ai->handle, sw, 1) < 0) {
        fprintf(stderr, "initialize_device(): cannot set min avail\n");
        return -1;
    }
#if 0
    /* always write as many frames as possible */
    if (snd_pcm_sw_params_set_xfer_align(ai->handle, sw, 1) < 0) {
        fprintf(stderr, "initialize_device(): cannot set transfer alignment\n");
        return -1;
    }
#endif
    /* play silence when there is an underrun */
    if (snd_pcm_sw_params_set_silence_size(ai->handle, sw, boundary) < 0) {
        fprintf(stderr, "initialize_device(): cannot set silence size\n");
        return -1;
    }
    if (snd_pcm_sw_params(ai->handle, sw) < 0) {
        fprintf(stderr, "initialize_device(): cannot set sw params\n");
        return -1;
    }
    return 0;
}
Beispiel #4
0
static int initialize_device(audio_output_t *ao)
{
	snd_pcm_hw_params_t *hw=NULL;
	snd_pcm_sw_params_t *sw=NULL;
	snd_pcm_uframes_t buffer_size;
	snd_pcm_uframes_t period_size;
	snd_pcm_format_t format;
	snd_pcm_t *pcm=(snd_pcm_t*)ao->userptr;
	unsigned int rate;
	int i;

	snd_pcm_hw_params_alloca(&hw); /* Ignore GCC warning here... alsa-lib>=1.0.16 doesn't trigger that anymore, too. */
	if (snd_pcm_hw_params_any(pcm, hw) < 0) {
		if(!0) printf("initialize_device(): no configuration available");
		return -1;
	}
	if (snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
		if(!0) printf("initialize_device(): device does not support interleaved access");
		return -1;
	}

#if 0
	format = SND_PCM_FORMAT_UNKNOWN;
	for (i = 0; i < NUM_FORMATS; ++i) {
		if (ao->format == format_map[i].mpg123) {
			format = format_map[i].alsa;
			break;
		}
	}
	if (format == SND_PCM_FORMAT_UNKNOWN) {
		if(!0) printf("initialize_device(): invalid sample format %d", ao->format);
		errno = EINVAL;
		return -1;
	}
#endif
    format = SND_PCM_FORMAT_S16_LE;
	if (snd_pcm_hw_params_set_format(pcm, hw, format) < 0) {
		if(!0) printf("initialize_device(): cannot set format %s", snd_pcm_format_name(format));
		return -1;
	}
	if (snd_pcm_hw_params_set_channels(pcm, hw, ao->channels) < 0) {
		if(!0) printf("initialize_device(): cannot set %d channels", ao->channels);
		return -1;
	}
	rate = ao->rate;
	if (snd_pcm_hw_params_set_rate_near(pcm, hw, &rate, NULL) < 0) {
		if(!0) printf("initialize_device(): cannot set rate %u", rate);
		return -1;
	}
	if (!rates_match(ao->rate, rate)) {
		if(!0) error2("initialize_device(): rate %ld not available, using %u", ao->rate, rate);
		/* return -1; */
	}
	buffer_size = rate * BUFFER_LENGTH;
	if (snd_pcm_hw_params_set_buffer_size_near(pcm, hw, &buffer_size) < 0) {
		if(!0) printf("initialize_device(): cannot set buffer size");
		return -1;
	}
	printf("buffer_size=%lu", (unsigned long)buffer_size);
	period_size = buffer_size / 4;
	if (snd_pcm_hw_params_set_period_size_near(pcm, hw, &period_size, NULL) < 0) {
		if(!0) printf("initialize_device(): cannot set period size");
		return -1;
	}
	if (snd_pcm_hw_params(pcm, hw) < 0) {
		if(!0) printf("initialize_device(): cannot set hw params");
		return -1;
	}

	snd_pcm_sw_params_alloca(&sw);
	if (snd_pcm_sw_params_current(pcm, sw) < 0) {
		if(!0) printf("initialize_device(): cannot get sw params");
		return -1;
	}
	/* start playing right away */
	if (snd_pcm_sw_params_set_start_threshold(pcm, sw, 1) < 0) {
		if(!0) printf("initialize_device(): cannot set start threshold");
		return -1;
	}
	/* wake up on every interrupt */
	if (snd_pcm_sw_params_set_avail_min(pcm, sw, 1) < 0) {
		if(!0) printf("initialize_device(): cannot set min available");
		return -1;
	}
#if SND_LIB_VERSION < ((1<<16)|16)
	/* Always write as many frames as possible (deprecated since alsa-lib 1.0.16) */
	if (snd_pcm_sw_params_set_xfer_align(pcm, sw, 1) < 0) {
		if(!0) printf("initialize_device(): cannot set transfer alignment");
		return -1;
	}
#endif
	if (snd_pcm_sw_params(pcm, sw) < 0) {
		if(!0) printf("initialize_device(): cannot set sw params");
		return -1;
	}
	return 0;
}