Ejemplo n.º 1
0
static int waveout_open(sample_format_t sf)
{
	WAVEFORMATEX  format;
	int rc, i;

	/* WAVEFORMATEX does not support channels > 2, waveOutWrite() wants little endian signed PCM */
	if (sf_get_bigendian(sf) || !sf_get_signed(sf) || sf_get_channels(sf) > 2) {
		return -OP_ERROR_SAMPLE_FORMAT;
	}

	memset(&format, 0, sizeof(format));
	format.cbSize = sizeof(format);
	format.wFormatTag = WAVE_FORMAT_PCM;
	format.nChannels = sf_get_channels(sf);
	format.nSamplesPerSec = sf_get_rate(sf);
	format.wBitsPerSample = sf_get_bits(sf);
	format.nAvgBytesPerSec = sf_get_second_size(sf);
	format.nBlockAlign = sf_get_frame_size(sf);

	if ((rc = waveOutOpen(&wave_out, WAVE_MAPPER, &format, 0, 0, CALLBACK_NULL)) != MMSYSERR_NOERROR) {
		switch (rc) {
		case MMSYSERR_ALLOCATED:
			errno = EBUSY;
			return -OP_ERROR_ERRNO;
		case MMSYSERR_BADDEVICEID:
		case MMSYSERR_NODRIVER:
			errno = ENODEV;
			return -OP_ERROR_ERRNO;
		case MMSYSERR_NOMEM:
			errno = ENOMEM;
			return -OP_ERROR_ERRNO;
		case WAVERR_BADFORMAT:
			return -OP_ERROR_SAMPLE_FORMAT;
		}
		return -OP_ERROR_INTERNAL;
	}

	/* reset buffers */
	for (i = 0; i < buffer_count; i++) {
		buffers[i].dwFlags = 0;
	}
	buffer_idx = 0;
	buffers_free = buffer_count;

	waveout_sf = sf;

	return 0;
}
Ejemplo n.º 2
0
static inline unsigned int buffer_second_size(void)
{
	return sf_get_second_size(buffer_sf);
}
Ejemplo n.º 3
0
Archivo: oss.c Proyecto: shawakaze/cmus
static int oss_set_sf(sample_format_t sf)
{
	int tmp, log2_fragment_size, nr_fragments, bytes_per_second;

	oss_reset();
	oss_sf = sf;

#ifdef SNDCTL_DSP_CHANNELS
	tmp = sf_get_channels(oss_sf);
	if (ioctl(oss_fd, SNDCTL_DSP_CHANNELS, &tmp) == -1)
		return -1;
#else
	tmp = sf_get_channels(oss_sf) - 1;
	if (ioctl(oss_fd, SNDCTL_DSP_STEREO, &tmp) == -1)
		return -1;
#endif

	if (sf_get_bits(oss_sf) == 16) {
		if (sf_get_signed(oss_sf)) {
			if (sf_get_bigendian(oss_sf)) {
				tmp = AFMT_S16_BE;
			} else {
				tmp = AFMT_S16_LE;
			}
		} else {
			if (sf_get_bigendian(oss_sf)) {
				tmp = AFMT_U16_BE;
			} else {
				tmp = AFMT_U16_LE;
			}
		}
	} else if (sf_get_bits(oss_sf) == 8) {
		if (sf_get_signed(oss_sf)) {
			tmp = AFMT_S8;
		} else {
			tmp = AFMT_U8;
		}
	} else if (sf_get_bits(oss_sf) == 32 && sf_get_signed(oss_sf)) {
		if (sf_get_bigendian(oss_sf)) {
			tmp = AFMT_S32_BE;
		} else {
			tmp = AFMT_S32_LE;
		}
	} else if (sf_get_bits(oss_sf) == 24 && sf_get_signed(oss_sf) && !sf_get_bigendian(oss_sf)) {
		tmp = AFMT_S24_PACKED;
	} else {
		d_print("unsupported sample format: %c%u_%s\n",
			sf_get_signed(oss_sf) ? 'S' : 'U', sf_get_bits(oss_sf),
			sf_get_bigendian(oss_sf) ? "BE" : "LE");
		return -1;
	}
	if (ioctl(oss_fd, SNDCTL_DSP_SAMPLESIZE, &tmp) == -1)
		return -1;

	tmp = sf_get_rate(oss_sf);
	if (ioctl(oss_fd, SNDCTL_DSP_SPEED, &tmp) == -1)
		return -1;

	bytes_per_second = sf_get_second_size(oss_sf);
	log2_fragment_size = 0;
	while (1 << log2_fragment_size < bytes_per_second / 25)
		log2_fragment_size++;
	log2_fragment_size--;
	nr_fragments = 32;

	/* bits 0..15 = size of fragment, 16..31 = log2(number of fragments) */
	tmp = (nr_fragments << 16) + log2_fragment_size;
	if (ioctl(oss_fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
		return -1;
	return 0;
}