コード例 #1
0
ファイル: jack.c プロジェクト: jolange/cmus
static int op_jack_open(sample_format_t sf, const channel_position_t *cm)
{
	sample_format = sf;

	if (fail) {
		/* jack went away so lets see if we can recover */
		if (client != NULL) {
			op_jack_exit();
		}
		if (op_jack_init() != OP_ERROR_SUCCESS) {
			return -OP_ERROR_INTERNAL;
		}
	}

	if (cm == NULL) {
		d_print("no channel_map\n");
		return -OP_ERROR_NOT_SUPPORTED;
	}
	channel_map = cm;

#ifdef HAVE_SAMPLERATE
	op_jack_reset_src();
	resample_ratio = (float) jack_sample_rate / (float) sf_get_rate(sf);
#else
	if (jack_sample_rate != sf_get_rate(sf)) {
		d_print("jack sample rate of %d does not match %d\n", jack_get_sample_rate(client), sf_get_rate(sf));
		return -OP_ERROR_SAMPLE_FORMAT;
	}
#endif

	if (sf_get_channels(sf) < CHANNELS) {
		d_print("%d channels not supported\n", sf_get_channels(sf));
		return -OP_ERROR_SAMPLE_FORMAT;
	}

	int bits = sf_get_bits(sf);

	if (bits == 16) {
		sample_bytes = 2;
		read_sample = sf_get_signed(sf) ? &read_sample_le16 : &read_sample_le16u;
	} else if (bits == 24) {
		sample_bytes = 3;
		read_sample = sf_get_signed(sf) ? &read_sample_le24 : &read_sample_le24u;
	} else if (bits == 32) {
		sample_bytes = 4;
		read_sample = sf_get_signed(sf) ? &read_sample_le32 : &read_sample_le32u;
	} else {
		d_print("%d bits not supported\n", sf_get_bits(sf));
		return -OP_ERROR_SAMPLE_FORMAT;
	}

	paused = false;
	return OP_ERROR_SUCCESS;
}
コード例 #2
0
ファイル: sndio.c プロジェクト: BG2BKK/cmus
static int sndio_set_sf(sample_format_t sf)
{
	struct sio_par apar;

	sndio_sf = sf;

	sio_initpar(&par);

	par.pchan = sf_get_channels(sndio_sf);
	par.rate = sf_get_rate(sndio_sf);
	sndio_paused = 0;

	if (sf_get_signed(sndio_sf))
		par.sig = 1;
	else
		par.sig = 0;

	if (sf_get_bigendian(sndio_sf))
		par.le = 0;
	else
		par.le = 1;

	switch (sf_get_bits(sndio_sf)) {
	case 16:
		par.bits = 16;
		break;
	case 8:
		par.bits = 8;
		break;
	default:
		return -OP_ERROR_SAMPLE_FORMAT;
	}

	par.appbufsz = par.rate * 300 / 1000;
	apar = par;

	if (!sio_setpar(hdl, &par))
		return -OP_ERROR_INTERNAL;

	if (!sio_getpar(hdl, &par))
		return -OP_ERROR_INTERNAL;

	if (apar.rate != par.rate || apar.pchan != par.pchan ||
	    apar.bits != par.bits || (par.bits > 8 && apar.le != par.le) ||
	    apar.sig != par.sig)
		return -OP_ERROR_INTERNAL;

	sndio_mixer_set_volume(sndio_volume, sndio_volume);

	if (!sio_start(hdl))
		return -OP_ERROR_INTERNAL;

	return OP_ERROR_SUCCESS;
}
コード例 #3
0
ファイル: waveout.c プロジェクト: dodamn/pkg-cmus
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;
}
コード例 #4
0
ファイル: roar.c プロジェクト: Brijen/cmus
static int op_roar_open(sample_format_t sf, const channel_position_t *channel_map)
{
    struct roar_audio_info info;
    int ret;

    memset(&info, 0, sizeof(info));

    ROAR_DBG("op_roar_open(*) = ?");

    format = sf;

    info.rate = sf_get_rate(sf);
    info.channels = sf_get_channels(sf);
    info.bits = sf_get_bits(sf);

    if (sf_get_bigendian(sf)) {
        if (sf_get_signed(sf)) {
            info.codec = ROAR_CODEC_PCM_S_BE;
        } else {
            info.codec = ROAR_CODEC_PCM_U_BE;
        }
    } else {
        if (sf_get_signed(sf)) {
            info.codec = ROAR_CODEC_PCM_S_LE;
        } else {
            info.codec = ROAR_CODEC_PCM_U_LE;
        }
    }

    ROAR_DBG("op_roar_open(*) = ?");

    if (roar_libroar_set_server(host) == -1) {
        ROAR_DBG("op_roar_open(*) = ?");

        roar_err_to_errno();
        return -OP_ERROR_ERRNO;
    }

    if ( roar_simple_connect2(&con, NULL, "C* Music Player (cmus)", ROAR_ENUM_FLAG_NONBLOCK, 0) == -1 ) {
        ROAR_DBG("op_roar_open(*) = ?");

        roar_err_to_errno();
        return -OP_ERROR_ERRNO;
    }

    vss = roar_vs_new_from_con(&con, &err);
    if (vss == NULL) {
        ROAR_DBG("op_roar_open(*) = ?");

        roar_disconnect(&con);

        _err_to_errno();
        return -OP_ERROR_ERRNO;
    }

    if (roar_vs_stream(vss, &info, ROAR_DIR_PLAY, &err) == -1) {
        ROAR_DBG("op_roar_open(*) = ?");

        roar_disconnect(&con);

        _err_to_errno();
        return -OP_ERROR_ERRNO;
    }

    ROAR_DBG("op_roar_open(*) = ?");

    if (roar_vs_buffer(vss, 2048*8, &err) == -1) {
        roar_vs_close(vss, ROAR_VS_TRUE, NULL);
        roar_disconnect(&con);
        _err_to_errno();
        return -OP_ERROR_ERRNO;
    }

    ROAR_DBG("op_roar_open(*) = ?");

    ret = _set_role();
    if (ret != 0) {
        roar_vs_close(vss, ROAR_VS_TRUE, NULL);
        roar_disconnect(&con);
        _err_to_errno();
        return ret;
    }

    ROAR_DBG("op_roar_open(*) = ?");

    if (roar_vs_blocking(vss, ROAR_VS_FALSE, &err) == -1) {
        /* FIXME: handle this error */
    }

    ROAR_DBG("op_roar_open(*) = 0");

    return 0;
}
コード例 #5
0
ファイル: oss.c プロジェクト: 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;
}